zoukankan      html  css  js  c++  java
  • 如何确定C++继承层次中的函数调用

      1 ```cpp
      2 
      3 
      4 //============================================================================
      5 // Name        : TS.cpp
      6 // Author      : jiudianren
      7 // Version     :
      8 // Copyright   : Your copyright notice
      9 // Description : Hello World in C++, Ansi-style
     10 //============================================================================
     11 
     12 #include <iostream>
     13 #include <functional>
     14 
     15 using namespace std;
     16 
     17 
     18 class A
     19 {
     20 protected:
     21     int m_data;
     22 public:
     23     A(int data = 0)
     24     {
     25         m_data = data;
     26     }
     27     int GetData()
     28     {
     29         return doGetData();
     30     }
     31     virtual int doGetData()
     32     {
     33         return m_data;
     34     }
     35 };
     36 
     37 
     38 
     39 class B: public A
     40 {
     41 protected:
     42     int m_data;
     43 public:
     44     B(int data = 1)
     45     {
     46         m_data = data;
     47     }
     48     int doGetData()
     49     {
     50         return m_data;
     51     }
     52 };
     53 
     54 
     55 class C: public B
     56 {
     57 protected:
     58     int m_data;
     59 public:
     60     C(int data = 2)
     61     {
     62         m_data = data;
     63     }
     64 
     65     int doGetData()
     66     {
     67         return m_data;
     68     }
     69 };
     70 
     71 void ref(C* & d)
     72 {
     73     cout<<d->GetData()<<endl;            //题1
     74     cout<<d->A::GetData()<<endl;         //题2
     75     cout<<d->B::GetData()<<endl;         //题3
     76     cout<<d->C::GetData()<<endl;         //题4
     77 
     78     cout<<d->doGetData()<<endl;          //题5
     79     cout<<d->A::doGetData()<<endl;       //题6
     80     cout<<d->B::doGetData()<<endl;       //题7
     81     cout<<d->C::doGetData()<<endl;       //题8
     82 }
     83 int main()
     84 {
     85     C c(10);
     86     cout<<c.GetData()<<endl;            //题1
     87     cout<<c.A::GetData()<<endl;         //题2
     88     cout<<c.B::GetData()<<endl;         //题3
     89     cout<<c.C::GetData()<<endl;         //题4
     90 
     91     cout<<c.doGetData()<<endl;          //题5
     92     cout<<c.A::doGetData()<<endl;       //题6
     93     cout<<c.B::doGetData()<<endl;       //题7
     94     cout<<c.C::doGetData()<<endl;       //题8
     95 
     96     cout<<"sssssssssss"<<endl;       //题8
     97     C *f=new C(11);
     98     C *d=f;
     99     cout<<d->GetData()<<endl;            //题1
    100     cout<<d->A::GetData()<<endl;         //题2
    101     cout<<d->B::GetData()<<endl;         //题3
    102     cout<<d->C::GetData()<<endl;         //题4
    103 
    104     cout<<d->doGetData()<<endl;          //题5
    105     cout<<d->A::doGetData()<<endl;       //题6
    106     cout<<d->B::doGetData()<<endl;       //题7
    107     cout<<d->C::doGetData()<<endl;       //题8
    108 
    109     cout<<"sssssssssss"<<endl;       //题8
    110     ref(f);
    111     return 0;
    112 }
    113 
    114 
    115 ```

    理解C++中继承层次的关键在于理解如何确定函数调用。确定函数调用遵循以下四个步骤:

    1)   首先确定进行函数调用的对象、引用或指针的静态类型。

    2)   在该类中查找函数,如果找不到,就在直接基类中查找,如此循着类的继承链往上找,直到找到该函数或者查找完最后一个类。如果不能在类或其相关类中找到该名字,则调用是错误的。

    3)   一旦找到了该名字,就进行常规类型检查,查看该函数调用是否合法。

    4)   <i>若函数调用合法,编译器就生成代码。如果函数是虚函数且通过引用或指针调用,则编译器生成代码以确定根据对象的动态类型运行哪个函数版本,否则,编译器生成代码直接调用函数。

    <ii>若函数调用不合法,则调用是错误的,且不再像(2)一样循着继承链往上找。

     

     

     

     

     

     

     

     

    题1----题8

    构造函数从最上层的基类开始构造,各个类的同名变量没有形成覆盖,都是单独的变量。
    1:
    静态类型为C类,故在C类中找GetData()函数,C类中没有GetData()函数,由步骤(2),在其直接基类B类中查找,B类中也没有,再在A类中找,在A类中找到,且常规类型检查无误,调用合法,运行之。在其函数体类调用的doGetData()是虚函数,但不是通过引用或指针调用,故没有动态绑定,则由静态类型决定调用哪一个版本的doGetData(),静态类型为C类,C类中没有doGetData(),在其基类B类中找,找到,运行之,返回的是B::m_data,其值为默认实参值1。故本行输出1。
    其他题类似,答案为1,1,1,1,1,0,1,1。

     

  • 相关阅读:
    最长递增子序列 LIS 时间复杂度O(nlogn)的Java实现
    动态规划算法(后附常见动态规划为题及Java代码实现)
    2个字符串的最长公共子串
    VS2010常用快捷键
    错误代码errno值的含义
    几个常用I/O函数用法(printf,fprintf等)
    查看CPU位数的方法
    关于函数指针的总结
    日本标点符号的输入总结
    共享内存及信号量的几个函数介绍
  • 原文地址:https://www.cnblogs.com/jiudianren/p/5657098.html
Copyright © 2011-2022 走看看