Item 36:不要重写继承来的非虚函数
来源:互联网 发布:与泰国人聊天软件 编辑:程序博客网 时间:2024/06/03 22:45
Item 36: Never redefine an inherited non-virtual function.
我们还是在讨论public继承,比如Derived
继承自Base
。如果Base
有一个非虚函数func
,那么客户会倾向认为下面两种调用结果是一样的:
Derived d;Base* pb = &d;Derived* pd = &d;// 以下两种调用应当等效pb->func();pd->func();
为什么要一样呢?因为public继承表示着"is-a"的关系,每个Derived
对象都是一个Base
对象(见Item 32)。
然而重写(override)非虚函数func
将会造成上述调用结果不一致:
class Base{public: void func(){}};class Derived: public Base{public: void func(){} // 隐藏了父类的名称func,见Item 33};
因为pb
类型是Base*
,pd
类型是Derived*
,对于普通函数func
的调用是静态绑定的(在编译期便决定了调用地址偏移量)。 总是会调用指针类型定义中的那个方法。即pb->func()
调用的是Base::func
,pd->func()
调用的是Derived::func
。
当然虚函数不存在这个问题,它是一种动态绑定的机制。
在子类中重写父类的非虚函数在设计上是矛盾的:
- 一方面,父类定义了普通函数
func
,意味着它反映了父类的不变式。子类重写后父类的不变式不再成立,因而子类和父类不再是"is a"的关系。 - 另一方面,如果
func
应当在子类中提供不同的实现,那么它就不再反映父类的不变式。它就应该声明为virtual
函数。
除非注明,本博客文章均为原创,转载请以链接形式标明本文地址: http://harttle.com/2015/09/03/effective-cpp-36.html
0 0
- Item 36:不要重写继承来的非虚函数
- 不要重新定义继承来的非虚函数
- Effective C++ Item 36 & 37 关于继承来的非虚函数和默认参数
- Item 37:不要重写父类函数的默认参数
- 重新定义继承而来的非虚函数
- C++ 重新定义继承而来的非虚函数
- 条款36、绝不重新定义继承而来的非虚函数
- Effective C++ Item 36 绝不重新定义继承而来的 non-virtual 函数
- 条款36:绝对不要重新定义继承而来的non-virtual函数
- 条款36:绝对不要重新定义继承而来的non-virtual函数
- effective C++笔记之条款36、37: 区分接口继承和实现继承、绝不要重新定义继承而来的非虚函数
- 决不要重新定义继承而来的非虚函数
- 《认清C++语言》---继承而来的非虚函数和缺省参数
- 决不要重新定义继承而来的非虚函数
- effective c++ 条款37: 决不要重新定义继承而来的非虚函数
- 决不要重新定义继承而来的非虚函数
- C++决不要重新定义继承而来的非虚函数
- 条款 37: 决不要重新定义继承而来的非虚函数
- Android自定义控件——自定义属性
- Android通过代码进行多屏幕适配
- 栈的压入、弹出序列
- Android 沉浸式状态栏总结
- 关于连接多个数据库的问题
- Item 36:不要重写继承来的非虚函数
- Python之从零开始:本博规划
- C++如何避免使用rand() % xxx的方式实现类似抽奖概率类的问题
- HIVE Exception in thread "main" java.lang.IncompatibleClassChangeError: Found class jline.Terminal,
- sed在shell中的简单应用
- centos 定时任务Crontab 使用实例
- Study schedule for new work.
- “钱三篇”后续之汇率(上)
- 常用嵌入式文件系统