如何确定C++继承层次中的函数调用
2012-08-27 15:42
274 查看
理解C++中继承层次的关键在于理解如何确定函数调用。确定函数调用遵循以下四个步骤:
(1) 首先确定进行函数调用的对象、引用或指针的静态类型。
(2) 在该类中查找函数,如果找不到,就在直接基类中查找,如此循着类的继承链往上找,直到找到该函数或者查找完最后一个类。如果不能在类或其相关类中找到该名字,则调用是错误的。
(3) 一旦找到了该名字,就进行常规类型检查,查看该函数调用是否合法。
(4) <i>若函数调用合法,编译器就生成代码。如果函数是虚函数且通过引用或指针调用,则编译器生成代码以确定根据对象的动态类型运行哪个函数版本,否则,编译器生成代码直接调用函数。
<ii>若函数调用不合法,则调用是错误的,且不再像(2)一样循着继承链往上找。
举例一:
构造函数从最上层的基类开始构造,各个类的同名变量没有形成覆盖,都是单独的变量。
题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。
(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。
相关文章推荐
- 理解 C++ 中继承层次的关键在于理解如何确定函数调用
- C++学习笔记之继承层次中的函数调用。
- C/C++: 函数调用, 栈的大小是如何被确定的
- C中如何调用C++函数?
- 如何在linux C/C++语言中调用 sqlite 的函数接口来实现对数据库的管理(转)
- c++程序里如何调用MATLAB中的函数
- 如何在c/c++中调用LUA函数
- C中如何调用C++函数
- 如何在C语言中调用C++编写的DLL中的函数
- c++里的system()函数调用系统命令如何获取打印信息
- 如何在C中调用C++函数 与 如何在C++中调用C的函数(待修改)
- c++ 如何把this指针传入成员函数 像全局函数一样调用成员函数
- (转)如何在linux C/C++语言中调用 sqlite 的函数接口来实现对数据库的管理
- Effective C++ 第五 六条C++默认编写调用哪些函数,如何明确拒绝自动生成的函数
- c++中如何解决函数调用二维数组的问题。
- C++继承时子类定义同名成员变量时的调用继承函数的问题
- 如何在C/C++语言中调用 sqlite 的函数
- c++中如何在主函数中调用其他文件内的函数?
- C++语言笔试题目 C++中为什么用模板类&& 类中如何使用const &&函数重载,我们靠什么来区分调用的那个函数?靠返回值判断可以不可以
- C++中如何调用C里面的函数