C++中继承覆写导致基类的成员不可见
2015-10-12 01:23
375 查看
在C++中,基类定义了一个成员函数 f(),派生类定义了一个成员函数 f(int),然后派生类来调用:pDerieved->f(),结果会怎样?
派生类的重载定义,会导致基类的函数在名称查找的时候,不可见。但是C++的设计哲学,又可以让你用using声明实现基类成员函数在派生类中重载。
代码一:
关于基类f()的隐藏,其实是因为类的作用域导致的,在C++中,派生类的作用域是嵌套在基类当中的。
编译器对类的成员进行名称查找的时候,编译器先在派生类当中查找,如果没找到,再到基类中查找,如果还没有找到,在到基类的基类中查找,一直查找到继承的最顶端。如果在继承的顶端还是没有找到,则报错。
本例中查找,x.f,编译器通过x的静态类型:Derive,在其作用域当中查找f(),
很幸运,编译器马上就找到了f(int),虽然函数签名不一样,但是函数名称一样,编译就不会继续往下查找了。但是f(int) 需要一个 int类型的参数,我们调用的参数少了,于是编译器报错。
代码二:
通过在派生类中声明基类的函数名称,在派生类中也能找到基类的函数了
执行结果:
AlexdeMacBook-Pro:~ alex$ a.out
f()
代码三:
编译器通过p的静态类型Base,找到了f(),于是调用了基类的f()
代码四:
执行结果:
AlexdeMacBook-Pro:~ alex$ a.out
f()
Derive f()
派生类的重载定义,会导致基类的函数在名称查找的时候,不可见。但是C++的设计哲学,又可以让你用using声明实现基类成员函数在派生类中重载。
代码一:
#include<iostream> #include<string> using namespace std; class Base { public: void f() { cout<<"f()"<<endl; } }; class Derive:public Base { public: void f(int i) { cout<<"f(int) i="<<i<<endl; } }; int main() { Derive x; x.f(1); //OK x.f(); //错误,参数格式错误。无参数的 f() 不可见 return 0; }
关于基类f()的隐藏,其实是因为类的作用域导致的,在C++中,派生类的作用域是嵌套在基类当中的。
编译器对类的成员进行名称查找的时候,编译器先在派生类当中查找,如果没找到,再到基类中查找,如果还没有找到,在到基类的基类中查找,一直查找到继承的最顶端。如果在继承的顶端还是没有找到,则报错。
本例中查找,x.f,编译器通过x的静态类型:Derive,在其作用域当中查找f(),
很幸运,编译器马上就找到了f(int),虽然函数签名不一样,但是函数名称一样,编译就不会继续往下查找了。但是f(int) 需要一个 int类型的参数,我们调用的参数少了,于是编译器报错。
代码二:
#include<iostream> #include<string> using namespace std; class Base { public: void f() { cout<<"f()"<<endl; } }; class Derive:public Base { public: using Base::f; //声明基类的作用域 void f(int i) { cout<<"f(int) i="<<i<<endl; } }; int main() { Derive x; x.f(); //ok return 0; }
通过在派生类中声明基类的函数名称,在派生类中也能找到基类的函数了
执行结果:
AlexdeMacBook-Pro:~ alex$ a.out
f()
代码三:
#include<iostream> #include<string> using namespace std; class Base { public: void f() { cout<<"f()"<<endl; } }; class Derive:public Base { public: void f(int i) { cout<<"f(int) i="<<i<<endl; } }; int main() { Derive x; Base *p=&x; p->f(); //OK return 0; }
编译器通过p的静态类型Base,找到了f(),于是调用了基类的f()
代码四:
#include<iostream> #include<string> using namespace std; class Base { public: void f() { cout<<"f()"<<endl; } }; class Derive:public Base { public: void f(int i) { cout<<"f(int) i="<<i<<endl; } void f() { cout<<"Derive f()"<<endl; } }; int main() { Derive x; Base *p=&x; p->f(); //OK x.f(); //OK return 0; }
执行结果:
AlexdeMacBook-Pro:~ alex$ a.out
f()
Derive f()
相关文章推荐
- C++基础---结构体(struct)
- C语言char和int的转换
- 初学算法 - 求凸包的Garham's Scan算法的C++实现
- 2015-10-12 OC语言中的多态 以及面向对象方法和继承的相关问题总结
- 丹尼斯·里奇:让乔布斯立足肩上的 C 语言之父
- 1082. Read Number in Chinese (25)
- 为何使用dynamic_cast转换类指针时,需要虚函数?
- C语言中的宏定义
- c++ primer第五版(中文)习题答案 第十章第三节第四小节-参数绑定
- STL之红黑树实现
- C++学习笔记17——函数重载
- STL之heap实现
- 黑马程序员——C语言学习笔记03 变量在内存中存储的细节、位运算
- 项目35.5 在北京买房
- 解决VC++ 6.0打开文件崩溃
- C++中的多态和派生继承
- 从c到c++<三>
- STL之简单空间适配器实现
- 欢迎使用CSDN-markdown编辑器
- C语言全局变量初始化、数据类型长度