0
点赞
收藏
分享

微信扫一扫

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


请看下面这段代码:

#include <iostream>

using namespace std;

class Base
{
public:
void Show()
{
cout << "I'm Base::Show()." << endl;
}
};

class Derive : public Base
{
public:
//遮盖了 Base::Show();
void Show()
{
cout << "I'm Derive::Show()." << endl;
}
};

int main()
{
Derive* pD = new Derive();
pD->Show(); //调用Derive::Show();

Base* pB = new Derive();
pB->Show(); //调用Base::Show();

return 0;
}

实现效果:

《Effective C++》36:绝不重新定义继承而来的non-virtual函数_代码

但是,这就让我们产生疑问了,pB指针明明指向的就是Derive对象,为什么会调用 Base::Show() 呢?

这是因为非虚函数Base::Show()和Derive::Show()都是静态绑定(statically bound)的。静态绑定是指在程序编译过程中,把函数(方法或者过程)调用与响应调用所需的代码结合的过程称之为静态绑定。这就意味着,由于pB被声明为指向Base类的指针,所以通过pB指针调用的所有的非虚函数永远是Base类所定义的版本。即使pB指向一个类型为Base的派生类的对象。

与此对应,virtual函数是动态绑定(dynamically bound)的。因此就不会有上面的问题。

如:

#include <iostream>

using namespace std;

class Base
{
public:
virtual void Show()
{
cout << "I'm Base::Show()." << endl;
}
};

class Derive : public Base
{
public:
//重写了 Base::Show();
virtual void Show()
{
cout << "I'm Derive::Show()." << endl;
}
};

int main()
{
Derive* pD = new Derive();
pD->Show(); //调用Derive::Show();

Base* pB = new Derive();
pB->Show(); //调用Derive::Show();

return 0;
}

实现效果:

《Effective C++》36:绝不重新定义继承而来的non-virtual函数_虚函数_02


对于引用,也会出现类似的情况。

因此,为了避免出现类似例子一的表述不明的现象,我们一般不要重新在子类定义非虚函数。



举报

相关推荐

0 条评论