effective C++笔记之条款36、37: 区分接口继承和实现继承、绝不要重新定义继承而来的非虚函数
2012-03-25 14:51
405 查看
条款36: 区分接口继承和实现继承
作为类的设计者,有时希望派生类只继承成员函数的接口(声明)(也即是纯虚函数);有时希望派生类同时继承函数的接口和实现,但允许派生类改写实现(即虚函数);有时希望同时继承接口和实现,并且不允许派生类改写任何东西(非虚函数)。
看如下这个类层次结构:
纯虚函数最显著的特征是:它们必须在继承了它们的任何具体类中重新声明,而且它们在抽象类中往往没有定义。定义纯虚函数的目的在于,使派生类仅仅是继承函数的接口。为一个纯虚函数提供定义也是可能的(注意这里,书上用纯虚函数来定义缺省实现)。但调用它的唯一方式是通过类名完整地指明是哪个调用。可以作为一种机制。
声明简单虚函数的目的在于,使派生类继承函数的接口和缺省实现。派生类可以选择改写或不改写他们。
声明非虚函数的目的在于,使派生类继承函数的接口和强制实现。
条款37:绝不要重新定义继承而来的非虚函数
先看如下类:
像B::mf和D::mf这样的非虚函数是静态绑定的。意味着pB被声明为指向B的指针类型,通过pB调用非虚函数时将总是调用那些定义在类B中的函数—即使pB指向的是从B派生的类的对象。
如果写类D时重新定义了从类B继承而来的非虚函数mf,D的对象就可能表现出精神分裂般的异常行为。也就是说,D的对象在mf被调用时,行为有可能像B,也有可能像D,决定因素和对象没有一点关系,而是取决于指向它的指针所声明的类型。引用也会和指针一样表现出这样的异常行为。
作为类的设计者,有时希望派生类只继承成员函数的接口(声明)(也即是纯虚函数);有时希望派生类同时继承函数的接口和实现,但允许派生类改写实现(即虚函数);有时希望同时继承接口和实现,并且不允许派生类改写任何东西(非虚函数)。
看如下这个类层次结构:
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++ Item 36 永远不要重新定义继承而来的非虚函数
- effective C++笔记之条款38: 绝不要重新定义继承而来的缺省参数值
- effective c++ 条款37: 决不要重新定义继承而来的非虚函数
- 条款37: 决不要重新定义继承而来的非虚函数
- Effective C++条款37:绝不重新定义继承而来的缺省参数值
- 《Effective C++ 》学习笔记-第六章 条款37:绝不重新定义继承而来的缺省参数值
- 绝对不要重新定义继承而来的non-virtual函数(Effective C++_36)
- 条款 37: 决不要重新定义继承而来的非虚函数
- Effective C++条款 37:绝不重新定义继承而来的缺省参数值
- Effective C++条款 37:绝不重新定义继承而来的缺省参数值
- 条款36:绝不重新定义继承而来的非虚函数
- Effective C++条款36解读: 绝不重新定义继承而来的non-virtual函数
- 读书笔记 effective c++ Item 37 永远不要重新定义继承而来的函数默认参数值
- 《effective C++》:条款36——绝不重新定义继承而来的非虚函数
- 条款37 绝不要重新定义继承而来的缺省参数值
- 条款36:绝对不要重新定义,继承而来的non-virtual函数
- 条款36:绝对不要重新定义继承而来的non-virtual函数
- 条款36:绝对不要重新定义继承而来的non-virtual函数
- 条款36: 区分接口继承和实现继承
- effective c++ 条款36: 区分接口继承和实现继承