可以直接调用的纯虚函数

昨天提到了子在构造函数和析构函数中调用虚函数的问题。白天的时候翻了一下《深入理解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

非原创文章文中已经注明原地址,如有侵权,联系删除

关注公众号【高性能架构探索】,第一时间获取最新文章

转载文章受原作者版权保护。转载请注明原作者出处!

(0)
上一篇 2023年2月9日 上午10:47
下一篇 2023年2月9日 上午10:47

相关推荐