effective C++笔记之条款36、37: 区分接口继承和实现继承、绝不要重新定义继承而来的非虚函数

原创 2012年03月25日 14:51:57

条款36: 区分接口继承和实现继承

  • 作为类的设计者,有时希望派生类只继承成员函数的接口(声明)(也即是纯虚函数);有时希望派生类同时继承函数的接口和实现,但允许派生类改写实现(即虚函数);有时希望同时继承接口和实现,并且不允许派生类改写任何东西(非虚函数)。
  • 看如下这个类层次结构:
class Shape
{
public:
     virtual void draw() const = 0;
     virtual void error(const string& msg);
     int objectID() const;
};
class Rectangle : public Shape {…};
class Ellipse : pulbic Shape {…};

  • 纯虚函数最显著的特征是:它们必须在继承了它们的任何具体类中重新声明,而且它们在抽象类中往往没有定义。定义纯虚函数的目的在于,使派生类仅仅是继承函数的接口。为一个纯虚函数提供定义也是可能的(注意这里,书上用纯虚函数来定义缺省实现)。但调用它的唯一方式是通过类名完整地指明是哪个调用。可以作为一种机制。
  • 声明简单虚函数的目的在于,使派生类继承函数的接口和缺省实现。派生类可以选择改写或不改写他们。   
  •  声明非虚函数的目的在于,使派生类继承函数的接口和强制实现。  

条款37:绝不要重新定义继承而来的非虚函数
  • 先看如下类:
class B
{
public:
    void mf();
};
class D : public B
{
public:
    void mf();
};
D x;
B *pB = &x;   
pB->mf();  //调用B::mf
D *pD = &x;
pD->mf();  //调用D::mf

像B::mf和D::mf这样的非虚函数是静态绑定的。意味着pB被声明为指向B的指针类型,通过pB调用非虚函数时将总是调用那些定义在类B中的函数—即使pB指向的是从B派生的类的对象。
  • 如果写类D时重新定义了从类B继承而来的非虚函数mf,D的对象就可能表现出精神分裂般的异常行为。也就是说,D的对象在mf被调用时,行为有可能像B,也有可能像D,决定因素和对象没有一点关系,而是取决于指向它的指针所声明的类型。引用也会和指针一样表现出这样的异常行为。

版权声明:本文为博主原创文章,未经博主允许不得转载。

相关文章推荐

《Effective C++ 》学习笔记-第六章 条款37:绝不重新定义继承而来的缺省参数值

Never redefine a function's inherited default parameter value

Effective C++条款 37:绝不重新定义继承而来的缺省参数值

重新定义一个继承而来的non-virtual函数永远都是错误的,本条款的讨论限制在“带有缺省参数的virtual函数”。 virtual函数是动态绑定的,而缺省参数却是静态绑定。对象的所谓静态类型,...

《Effective C++》读书笔记之item37:绝不重新定义继承而来的缺省参数值

1.绝不重新定义继承而来的缺省参数值,它有两层意思: (1)如果函数是非虚函数,你根本不应该重新定义它,因此也谈不上改变缺省参数值了。(2)如果函数是虚函数,由于缺省参数值是“静态绑定”,即使使...

关于C++虚函数默认参数的问题。Effective C++ 条款38: 决不要重新定义继承而来的缺省参数值

昨晚在chgaowei的博客上关于讨论C++虚函数的默认参数问题,刚翻书找了一下,在Effective C++ 中的38条有说明。直接上原文吧,最后加几句细点的理解条款38: 决不要重新定义继承而来的...

C++之绝不重新定义继承而来的non-virtual函数(36)---《Effective C++》

条款36:绝不重新定义继承而来的non-virtual函数这篇博客我们主要讲解一下为什么派生类Derived不能重新定义父类Base中的non-virtual函数,在分析之前,请大家分析一下如下代码:...

C++ 重新定义继承而来的非虚函数

之前在Effective C++看到有一个条款:决不要重新定义继承而来的非虚函数,今天在看代码的时候,发现有人重新定义继承而来的非虚函数,所以重新查看了这个条款。虽然这样做(重新定义继承而来的非虚函数...

条款36:绝不重新定义继承而来的non-virtual函数

//绝不重新定义继承而来的non-virtual函数 #include using namespace std; class B{ public: void mf() {cout << "调用...

C++决不要重新定义继承而来的非虚函数

Effective C++有条款说明这个问题的 条款37: 决不要重新定义继承而来的非虚函数 有两种方法来看待这个问题:理论的方法和实践的方法。让我们先从实践的方法开始。毕竟,理论家一般都很耐心。 ...

C++之绝不重新定义继承而来的缺省参数值(37)---《Effective C++》

条款37:绝不重新定义继承而来的缺省参数值首先让我们进行分析,类的继承中只能继承两种函数,virtual和non-virtual,然鹅重新定义一个继承而来的non-virtual函数永远是错误的,所以...

条款37:绝不重新定义继承而来的缺省参数

先上代码: class Base { public: virtual int getVal(int i = 0) { cout<<"基类函数"<<endl; return i...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

(最多只允许输入30个字)