[C++再学习系列] 派生类函数的重实现规则(override-覆盖)-阿里云开发者社区

开发者社区> 技术小美> 正文

[C++再学习系列] 派生类函数的重实现规则(override-覆盖)

简介:
+关注继续查看

  对于用过C++的人大体都清楚:派生类可以重实现基类中声明为virtual的函数,并且很清楚如果想实现正确的重写,必须满足:派生类重实现的函数的所有属性和基类virtual函数一致,即函数签名,const限制均一样。同时为了更好地传达代码意图,重实现的virtual函数最好添加冗余的virtual关键字。

  上面这些是基本要求,对于重实现,还有3个需要注意的地方:

  1) 保证可替换性: 任何派生类都必须遵守基类所承诺的前条件和后条件。当然改写后函数可以要求更少保证更多,反之不行。

  2) 永远不要修改默认参数。切记:默认参数并非函数签名的组成部分,修改重实现函数的默认参数,并不会导致重实现失败,但会导致糟糕的默认参数错误。对于调用者而言,同一个对象的成员函数会不加提示地根据自己访问所使用的静态类型而接受不同的参数。换句话说,重实现函数的默认参数并不具有多态属性。

  3)  谨防基类重载(overload)函数被重实现函数所隐藏(overwrite)。(这和C++的名字查找相关)

示例1:默认参数问题

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

};

相关文章:

揭秘:C++编译器的函数编译流程

[C++再学习系列] Using声明和指令的工作原理

---------------------------------------------------

兄弟的公司:立即购--手机购物,诚信网购

欢迎转载,请注明作者和出处。

本文转自 zhenjing 博客园博客,原文链接:http://www.cnblogs.com/zhenjing/archive/2010/12/02/override_overwrite_overload.html   ,如需转载请自行联系原作者


版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
Java总结 - List实现类Vector&Stack
由于之前 对ArrayList和LinkedList的分析,所以在看Vector和Stack的源码实现就会非常简单 观察上图,我们可以看到本文要说的Stack和Vector是父子关系,我们依旧从源码入手,期望能够对你有帮助,如果本文有理解不对的地方,请及时指正,谢谢您 Vector 我们知道...
1524 0
linux中命名规则_学习笔记
时间:2017.11.24作者:李强参考:man,info,magedu讲义声明:以下英文纯属个人翻译,英文B级,欢迎纠正,以下内容纯属个人理解,并没有对错,只是参考,盗版不纠,才能有限,希望不误人子弟为好。
693 0
写一个函数对字符串数组排序,使所有变位词都相邻
题目 写一个函数对字符串数组排序,使得所有的变位词都相邻。 解答 首先,要弄清楚什么是变位词。变位词就是组成的字母相同,但顺序不一样的单词。 比如说:live和evil就是一对变位词。OK,那么这道题目的意思就很清楚了, 它并不要求我们将字符串数组中的字符串按字典序排序,否则我们直接调用STL中的sort 函数就可以了。
762 0
+关注
6906
文章
0
问答
文章排行榜
最热
最新
相关电子书
更多
《2021云上架构与运维峰会演讲合集》
立即下载
《零基础CSS入门教程》
立即下载
《零基础HTML入门教程》
立即下载