条款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 void Derived::mf()
21 {
22     cout << "Derived::mf" << endl;
23 }
24
25 int main()
26 {
27     Derived d;
28
29     Base* pB = &d;
30     pB->mf();           // 调用Base::mf
31     Derived* pD = &d;
32     pD->mf();           // 调用Derived::mf
33
34     return 0;
35 }

说明:同样都指向d,但是却调用了不同的函数,原因是非虚函数是静态绑定的,即调用哪个函数是由声明时所决定的。而虚函数是动态绑定的,调用哪个函数是由运行时指向的对象决定的。

如上所述,如果重新定义了继承而来的非虚函数,那么得到的结果可能并不是你想要的;如果确实需要重新实现自己的函数版本,那么定义为虚函数好了。

时间: 2024-10-31 14:54:52

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

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

class B { public: void mf(); ... }; class D: public B { ... }; 甚至对B,D或mf一无所知,也可以定义一个类型D的对象x, D x;                          // x是类型D的一个对象 那么,如果发现这么做: B *pB = &x;                   // 得到x的指针 pB->mf();                     // 通过指针调用mf 和下面这么做的执行行为不一样: D

[条款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,凭

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

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

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

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函数的缺省参数值不能被重新定

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

在继承中,分为两类函数:virtual和non-virtual.而重新定义一个非虚函数是不好的(条款36),那么以下的讨论就是如何定义继承而来的虚函数. 强调:虚函数是动态绑定的,而缺省参数值是静态绑定的. 1 #include <iostream> 2 3 class Shape 4 { 5 public: 6 enum ShapeColor{ Red, Green, Blue }; 7 virtual void draw(ShapeColor color = Red) const = 0;

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

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

首先,此处的函数指的是 virtual 函数,为什么不是non-virtual函数呢?是因为在public继承中,non-virtual函数表示派生类是需要继承其接口与其强制实现的.如果你的Derived已经在考虑重写non-virtual函数了,那么你是应该好好审视一下,在此处使用 public继承是否合理了. 因此,本文只讲解virtual函数的缺省参数值,例如下面的代码: 在C++代码中,函数的参数值是静态绑定的,而通过基类的指针或者引用对virtual函数调用的动态绑定的. 因此,当你的