您的位置:首页 > 编程语言 > C语言/C++

如何确定C++继承层次中的函数调用

2012-08-27 15:42 274 查看
理解C++中继承层次的关键在于理解如何确定函数调用。确定函数调用遵循以下四个步骤:
(1) 首先确定进行函数调用的对象、引用或指针的静态类型。
(2) 在该类中查找函数,如果找不到,就在直接基类中查找,如此循着类的继承链往上找,直到找到该函数或者查找完最后一个类。如果不能在类或其相关类中找到该名字,则调用是错误的。
(3) 一旦找到了该名字,就进行常规类型检查,查看该函数调用是否合法。
(4) <i>若函数调用合法,编译器就生成代码。如果函数是虚函数且通过引用或指针调用,则编译器生成代码以确定根据对象的动态类型运行哪个函数版本,否则,编译器生成代码直接调用函数。
<ii>若函数调用不合法,则调用是错误的,且不再像(2)一样循着继承链往上找。

举例一:

#include <iostream>
#include <functional>

using namespace std;

class A
{
protected:
int m_data;
public:
A(int data = 0)
{
m_data = data;
}
int GetData()
{
return doGetData();
}
virtual int doGetData()
{
return m_data;
}
};

class B: public A
{
protected:
int m_data;
public:
B(int data = 1)
{
m_data = data;
}
int doGetData()
{
return m_data;
}
};

class C: public B
{
protected:
int m_data;
public:
C(int data = 2)
{
m_data = data;
}
};

int main()
{
C c(10);
cout<<c.GetData()<<endl;            //题1
cout<<c.A::GetData()<<endl;         //题2
cout<<c.B::GetData()<<endl;         //题3
cout<<c.C::GetData()<<endl;         //题4

cout<<c.doGetData()<<endl;          //题5
cout<<c.A::doGetData()<<endl;       //题6
cout<<c.B::doGetData()<<endl;       //题7
cout<<c.C::doGetData()<<endl;       //题8

return 0;
}


构造函数从最上层的基类开始构造,各个类的同名变量没有形成覆盖,都是单独的变量。

题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。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: