派生类函数的重实现规则(override-覆盖)
来源:互联网 发布:vr培训机构 知乎 编辑:程序博客网 时间:2024/06/06 12:46
派生类函数的重实现(override-覆盖)规则
对于用过C++的人大体都清楚:派生类可以重实现基类中声明为virtual的函数,并且很清楚如果想实现正确的重写,必须满足:派生类重实现的函数的所有属性和基类virtual函数一致,即函数签名,const限制均一样。同时为了更好地传达代码意图,重实现的virtual函数最好添加冗余的virtual关键字。
上面这些是重写的基本要求,对于重实现,还有3个需要注意的地方:
1) 保证可替换性: 任何派生类都必须遵守基类所承诺的前条件和后条件。当然改写后函数可以要求更少保证更多,反之不行。
2) 永远不要修改默认参数。切记:默认参数并非函数签名的组成部分,修改重实现函数的默认参数,并不会导致重实现失败,但会导致糟糕的默认参数错误。对于调用者而言,同一个对象的成员函数会不加提示地根据自己访问所使用的静态类型而接受不同的参数。换句话说,重实现函数的默认参数并不具有多态属性。
3) 谨防基类重载(overload)函数被重实现函数所隐藏(overwrite),。(这和C++的名字查找相关)
示例:默认参数问题:
class Base { //… virtual void Foo( int x = 0 ); }; class Derived : public Base { //… virtual void Foo( int x = 1 ); // poor form, and surprise-inducing }; Derived *pD = new Derived; pD->Foo(); // invokes pD->Foo(1) Base *pB = pD; pB->Foo(); // invokes pB->Foo(0) 示例:隐藏基类重载函数: class Base{// … virtual void Foo( int ); virtual void Foo( int, int ); voidFoo( int, int, int ); }; class Derived : public Base {// … virtual void Foo( int ); // overrides Base::Foo(int), but hides theothers }; Derived d; d.Foo( 1 ); // ok d.Foo( 1, 2 ); // error (oops?) d.Foo( 1, 2, 3 ); // error (oops?)
问题产生的原因:C++编译器的编译过程分3步:名字查找,重载解析和访问性检查。为加快名字查找速度,编译器是逐步扩大名字查找范围的。以上述例子为例:d.Foo( 1, 2 ); 在名字查找时,编译器首先发现派生类存在Foo函数,并停止名字查找;接着进行函数的重载解析,并发现派生类中,并未找到合适函数签名的Foo函数,报错!
解决方案:使用using引入基类的特定名字(见< Using声明和指令的工作原理>)。
class Derived : public Base {// …
virtual void Foo( int ); // overrides Base::Foo(int)
using Base::Foo; // bring the other Base::Foooverloads into scope
};
- 派生类函数的重实现规则(override-覆盖)
- 派生类函数的重实现规则(override-覆盖)
- 派生类函数的重实现规则(override-覆盖)
- [C++再学习系列] 派生类函数的重实现规则(override-覆盖)
- 派生类构造函数规则
- 派生类构造函数规则
- 派生类覆盖基类的重载的函数
- 派生类的对象访问基类中被派生类覆盖或隐藏了的函数或变量
- 派生类的对象访问基类中被派生类覆盖或隐藏了的函数或变量
- 函数的覆盖(override)与隐藏
- 派生类的派生类中(override)的表现
- 派生类的基本函数的实现
- 如何实现派生类的基本函数
- 派生类构造函数,重构
- 派生类成员函数对基类成员函数的覆盖
- C++继承详解之二——派生类成员函数详解(函数隐藏、构造函数与兼容覆盖规则)
- 函数重载(overload)和函数重写(override)的基本规则
- 派生类构造函数与析构函数的构造规则
- openwrt的一些琐事
- golang里channel的实现原理
- MySQL-5.6.15解压版(zip版)安装配置教程
- 算法时间复杂度的计算
- Linux Centos下软件的安装与卸载方法
- 派生类函数的重实现规则(override-覆盖)
- OpenCV学习:Mat类详细解析+源码剖析(三)遍历矩阵中元素
- C++,ifndef和ifdef的区别
- JSP 通过href调用Java中的servlet
- 计算机网络中每一层的协议总结
- 任务中心,预警平台练习
- PHP中如何获取当前时间及比较
- C++TR1学习笔记之tuple
- css弹出层 覆盖底层