Effective C++ Item 36 绝不重新定义继承而来的 non-virtual 函数

本文为senlie原创,转载请保留此地址:http://blog.csdn.net/zhengsenlie

经验:绝对不要重新定义继承而来的 non-virtual 函数 --> Item 7 "为多态基类声明 virtual 析构函数" 是本条款的特例

示例:

class B{
public:
	void mf();
	//...
};
class D: public B{
public:
	void mf(); // 遮掩了B::mf,Item 33 名称遮掩规则
}

D x;
B *pB = &x;
D *pD = &x;
pB->mf(); // 调用  B::mf
pD->mf(); // 调用  D::mf

解析:

1.non-virtual函数是静态绑定的。 pB声明的类型(pointer-to-B)是静态的,而pB指向的类型(class D)是动态的,

通过pB 调用的 non-virtual函数永远是B所定义的版本

2.

public 继承意味着is-a,适用于B对象的每一件事,也适用于D对象,因为每个D对象都是一个B对象

不变性凌驾特异性,B的derived classes一定会继承 mf 的接口和实现,因为 mf是B的一个 non-virtual 函数

重新定义继承 non-virtual函数后产生的茅盾:

如果D真有必要实现出与B不同的mf,那么“每个D都是一个B”就不为真,就不应该以 public 形式继承 B

如果D真的必须以 public 形式继承B,并且如果D越有需要实现出与B不同的 mf,那mf就无法为B反映出“不变性凌驾特异性”的性质

Effective C++ Item 36 绝不重新定义继承而来的 non-virtual 函数

时间: 2024-08-04 04:01:37

Effective C++ Item 36 绝不重新定义继承而来的 non-virtual 函数的相关文章

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

本文为senlie原创,转载请保留此地址:http://blog.csdn.net/zhengsenlie 经验:绝对不要重新而来的缺省参数值,因为缺省参数值都是静态绑定,而 virtual 函数 -- 你唯一应该覆写的东西 -- 却是动态绑定 示例: class Shape{ public: enum ShapeColor {Red, Green, Blue}; virtual void draw(ShapeColor color = Red) const = 0; }; class Rect

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

1. public继承意味着is-a关系,即派生类是基类的一种,任何基类可以进行的操作派生类也应该可以进行,如果派生类对于某个函数的实现与基类不同,那么就应当这个函数设为virtual,如果基类中的某个函数是non-virtual的,那么也应该意味着派生类应该继承这个函数的实现,而不应该重定义它. 2. 由于non-virtual函数采用静态绑定,如果对其进行重定义,那么经由指向派生类对象的基类指针调用的non-virtual函数将会是基类版本,这与期望不同,因此要override就设为virt

Effective C++ Item 09-绝不在构造函数和析构函数中调用virtual函数

Item 09-绝不在构造函数和析构函数中调用virtual函数(Never call virtual functions during construction or destruction) Why? 由于base class构造函数的执行更早于derived class构造函数,当base class构造函数执行derived class的成员变量尚未初始化.如果期间调用的virtual函数下降至derived class阶层,要知道derived class的函数几乎必然取用local成

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

看下面的两个类的声明代码: class B { public: void mf(); //something to do }; class D : public B { public: void mf(); }; 如果有下面的调用: D x; //第一种调用 B *pB = &x; pB->mf();//调用B::mf //第二种调用 D *pD = &x; pD->mf();//调用D::mf 这两种调用的行为是不一样的,虽然从表面上看,两者都是通过对象x调用成员函数mf,凭

条款36:绝不重新定义继承而来的非虚函数

1 #include <iostream> 2 3 using namespace std; 4 5 class Base 6 { 7 public: 8 void mf(); 9 }; 10 void Base::mf() 11 { 12 cout << "Base::mf" << endl; 13 } 14 15 class Derived : public Base 16 { 17 public: 18 void mf(); 19 }; 20

Effective C++ Item 34 区分接口继承与实现继承

本文为senlie原创,转载请保留此地址:http://blog.csdn.net/zhengsenlie 关联条款 Item 36 接口继承和实现继承不同.在 public 继承下, derived classes 总是继承 base class 的接口 class Shape{ public: virtual void draw() const = 0; virtual void error(const std::string &msg); int objectID() const; //.

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

(一)首先有下面的继承体系: class B { public: void mf(); ... }; class D : public B {...}; D x; 以下行为: B* pB = &x; pB->mf(); 异于以下行为: D* pD = &x; pD->mf(); 上面两种行为产生的结果不一定相同.看下面这种情况: mf是个non-virtual函数而D定义有自己的mf版本: class D : public B { public: void mf(); ...

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

由于重新定义继承而来的non-virtual函数是不正确的(见上一个条款),所以这个条款就将问题局限于:绝不重新定义继承一个带有缺省参数值的virtual函数. (一) virtual函数是动态绑定的,而缺省参数却是静态绑定. 对象的所谓静态类型,是它在程序中被声明时所采用的类型. 你可能会在"调用一个定义于derived class 内的virtual函数"的同时,却使用了base class为它所指定的缺省参数值. (二) 为什么继承而来的virtual函数的缺省参数值不能被重新定

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

Item 37:绝不重新定义继承而来的缺省参数值 Item 37:Never redefine a function's inherited default parameter value 本条款的讨论局限于:继承一个带有缺省参数值的virtual函数. 本条款成立的理由是:virtual函数是动态绑定(dynamically bound),而缺省参数却是静态绑定(statically bound). 静态绑定又名前期绑定,early binding:动态绑定又名后期绑定,late bindin