绝对不要重新定义继承而来的non-virtual函数(Effective C++_36)
2015-09-15 10:41
459 查看
一、对于非虚函数同一个对象调用同一个函数,可能产生了不同的行为
结果:
再看以下代码
唯一的区别是,重写了mf()函数,但结果却不同
造成这一原因是pb被声明为一个指向类型B的的指针,通过pb调用的非虚函数永远是B的版本,即使pb是指向一个类型为B的派生类的对象,这是因为非虚函数是静态绑定,在编译时就已经确定
假设mf()被声明为虚函数,那么无论是pb还是pD调用mf(),结果都会是D,因为pb和pD真正指的都是一个类型为D的对象
所以如果在实现类D时,对基类B非虚函数mf重写。当D的对象在调用mf时,行为有可能象B,也有可能象D,决定因素跟对象本身没有关系,反而是取决于指向它的指针所声明的类型。引用也会和指针一样表现出这样的异常行为。
总结:任何条件下都要禁止重新定义继承而来的非虚函数
参考:<
class B{ public: void mf(){ cout<<"B"<<endl; } }; class D:public B{ }; int main(){ D x; B* pb=&x;//获得一个B类型的指针指向x pb->mf(); D* pD=&x;//获得一个D类型的指针指向x pD->mf(); return 0; }
结果:
B B 请按任意键继续. . .
再看以下代码
class B{ public: void mf(){ cout<<"B"<<endl; } }; class D:public B{ public: void mf(){//名字覆盖 cout<<"D"<<endl; } }; int main(){ D x; B* pb=&x; pb->mf(); D* pD=&x; pD->mf(); return 0; }
唯一的区别是,重写了mf()函数,但结果却不同
B D 请按任意键继续. . .
造成这一原因是pb被声明为一个指向类型B的的指针,通过pb调用的非虚函数永远是B的版本,即使pb是指向一个类型为B的派生类的对象,这是因为非虚函数是静态绑定,在编译时就已经确定
假设mf()被声明为虚函数,那么无论是pb还是pD调用mf(),结果都会是D,因为pb和pD真正指的都是一个类型为D的对象
所以如果在实现类D时,对基类B非虚函数mf重写。当D的对象在调用mf时,行为有可能象B,也有可能象D,决定因素跟对象本身没有关系,反而是取决于指向它的指针所声明的类型。引用也会和指针一样表现出这样的异常行为。
总结:任何条件下都要禁止重新定义继承而来的非虚函数
参考:<
相关文章推荐
- C++Primer第五版 6.2.4节练习
- 浅谈 C++ 中的 new/delete 和 new[]/delete[]
- C++Primer第五版 6.2.3节练习
- OpenCV/source/sample/cpp的学习
- c/c++中delete/free 指针后,设置p=NULL的好处
- C++动态特性和C++对象模型——《高质量程序设计12章》
- C++ typedef typename
- C++中string类解析
- C++之static_cast, dynamic_cast, const_cast
- C++全局函数与类成员函数的区别和相互转化
- C++ int function() const; 怎么理解?
- 总结c/c++中各种基本数据类型转换方法
- C++和java多态的区别
- C++从零开始
- C语言中memset函数详解
- Eclipse+CDT+MinGW 配置 C/C++ 开发环境
- 浅析C++中的static(一些补充)
- 浅析C++中的static(一些补充)
- C语言中memset函数详解
- 2015C++暑期实训(上)