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,决定因素和对象没有一点关系,而是取决于指向它的指针所声明的类型。引用也会和指针一样表现出这样的异常行为。

条款34 区分接口继承和实现继承

总结: 1.  接口继承&实现继承不同。在public继承之下,derived classes总是继承base class的接口。 2.  pure virtual纯虚函数只具体指定接...
  • u013074465
  • u013074465
  • 2015年07月06日 09:03
  • 669

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

(公有)继承的概念看起来很简单,进一步分析,会发现它由两个可分的部分组成:函数接口的继承和函数实现的继承. class Shape { public: virtual void draw() con...
  • lujiandong1
  • lujiandong1
  • 2014年12月17日 13:56
  • 314

C++接口继承与实现继承的区别和选择

1.接口继承与实现继承的区别《Effective C++》条款三十四:区分接口继承和实现继承中介绍的比较啰嗦,概括地说需要理解三点: (1)纯虚函数只提供接口继承,但可以被实现; (2)虚函数既提...
  • K346K346
  • K346K346
  • 2017年02月13日 16:34
  • 620

条款 37: 决不要重新定义继承而来的非虚函数

假设类 D 公有继承于类 B,并且类 B 中定义了一个公有成员函数 mf。mf的参数和返回类型不重要,所以假设都为 void。换句话说,我这么写:      class B { public: vo...
  • lujiandong1
  • lujiandong1
  • 2014年12月31日 16:53
  • 472

C++中的接口继承和实现继承

C++中的接口继承和实现继承 很多人认为,C++中是不存在接口继承的,只有Java、C#这类语言才提供了相应的语法支持。 但是,如同鲁迅说过的某句名言:世上本没有接口继承,用的...
  • passtome
  • passtome
  • 2013年07月01日 11:00
  • 5300

Effective C++ 条款34 区分接口继承和实现继承

关于飞机问题代码如下: #include #include using namespace std; class Airport { public: Airport(){} Airport(ch...
  • u013654533
  • u013654533
  • 2014年05月28日 16:48
  • 420

关于c++的多继承(有关接口)

大家在学java C#的时候一定会看到类似这样的话“一些语言如C++支持所谓的‘多重继承’,即一个类派生于多个类。使用多重继承优点是有争议的:一方面,可以使用多重继承编写非常复杂、但很紧凑的代码;另一...
  • u010458863
  • u010458863
  • 2013年12月27日 23:11
  • 1072

Effective C++:条款34:区分接口继承和实现继承

(一) class Shape { public: virtual void draw() const = 0; virtual void error(const string...
  • u010470972
  • u010470972
  • 2014年06月28日 12:49
  • 588

《Effective C++》:条款34:区分接口继承和实现继承

public继承的概念,由2部分构成:函数接口(function Interface)继承和函数实现(function implementation)继承。这两种继承的差异有点像函数的声明和函数的定义...
  • KangRoger
  • KangRoger
  • 2015年02月26日 23:36
  • 1311

读书笔记《Effective C++》条款34:区分接口继承和实现继承

成员函数的接口总是会被继承。如条款32所说,public继承意味is-a,所以对base class为真的任何事情一定也对其derived class为真。因此如果某个函数可施行于某class身上,一...
  • u014558668
  • u014558668
  • 2017年05月25日 23:35
  • 58
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:effective C++笔记之条款36、37: 区分接口继承和实现继承、绝不要重新定义继承而来的非虚函数
举报原因:
原因补充:

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