昨天提到了子在构造函数和析构函数中调用虚函数的问题。白天的时候翻了一下《深入理解C++对象模型》,结果还真发现一点儿有趣的东西。
文中如是说:很多C++新手会惊奇的发现纯虚函数竟然可以定义(在声明的基类中定义),并且可以被调用(静态调用)!看来我还是新手啊,废话少说,上代码!
#include <iostream>
using namespace std;
class Base{
public:
Base(){}
void callVirFunc();
virtual ~Base(){};
private:
virtual void virFunc() = 0;//注意是私有的哦!
};
class Derived:public Base{
public:
Derived(){}
private:
virtual void virFunc();//这里也是私有的哦!
};
void Base::virFunc(){
cout<<"Virtual function static defined in Base!"<<endl;
}
void Base::callVirFunc(){
virFunc();//调用Derived class中的实现版本
Base::virFunc();//调用Base class中的static版本
}
void Derived::virFunc(){
cout<<"Virtual function defined in Derived!"<<endl;
}
int main(){
Base *pd = new Derived;
pd->callVirFunc();
delete pd;
return 0;
}
运行结果:
:!./pure_virtual_func_test
Virtual function defined in Derived!
Virtual function static defined in Base!
例子中, Base class中的callVirFunc函数分别调用了在Base class中定义的纯虚函数版本和Derived class中的实现版本。神奇吧!
其实这个例子是很特殊的哦!它还是反映了另外一个有趣的问题哦!注意!Base class中的callVirFunc函数调用了Derived class中的私有虚函数!它竟然绕过了访问控制机制!对于这个问题,CSDN中的兄弟们进行了激烈的讨论(在这里http://topic.csdn.net/t/20040805/16/3245820.html)。我想说的是,从编译器的角度看,这是完全没有问题的,因为当前对象的类类型是Derived,它的vptr指向Derived的虚函数表。还有一个问题就是,在虚函数表中并没有访问控制信息,所以此时调用虚函数的时候,拿到的当然就是Derived的版本并正确执行喽。这种做法确实可以造成一些看起来诡异的程序行为,所以尽量避免这样做吧。如果想让程序更有序,更清晰,在虚函数中调用私有的本地函数是比较好的方式。
原文链接: https://www.cnblogs.com/chezxiaoqiang/archive/2012/09/18/2692378.html
欢迎关注
微信关注下方公众号,第一时间获取干货硬货;公众号内回复【pdf】免费获取数百本计算机经典书籍
原创文章受到原创版权保护。转载请注明出处:https://www.ccppcoding.com/archives/63161
非原创文章文中已经注明原地址,如有侵权,联系删除
关注公众号【高性能架构探索】,第一时间获取最新文章
转载文章受原作者版权保护。转载请注明原作者出处!