一般情况下,不允许在构造函数或者析构函数中调用虚函数。其实语法上都没有问题,只是会失去多态性。

如果在构造函数中调用虚函数,会先调用父类中的实现,也就失去了多态的性质。

class A {public:virtual void print() {cout << "A" << endl;}A() {print();}~A() {//print();
    }
};
class B :public A {void print() {cout << "B" << endl;}
};
int main() {A* ptr = new B;return 0;
}

如果在析构函数中调用虚函数,也是同样的失去了多态性。

class A {public:virtual void print() {cout << "A" << endl;}A() {print();}~A() {print();}
};
class B :public A {void print() {cout << "B" << endl;}
};
int main() {A* ptr = new B;delete ptr;return 0;
}

出现上述结果的原因是因为,构造函数还没有将vptr和vtable初始化完毕,就调用虚函数,此时必然调用的基类中的实现。

而在析构函数中,因为子类的那部分已经被析构掉了,此时在父类的析构函数调用虚函数,调用的也只能是父类中的实现。


但是吧,也有的文章说如果一个类为基类的时候,必须将析构函数写为虚函数,否则子类那部分无法释放。

https://blog.csdn.net/starlee/article/details/619827

我们知道,用C++开发的时候,用来做基类的类的析构函数一般都是虚函数。可是,为什么要这样做呢?下面用一个小例子来说明:    
    有下面的两个类:

class ClxBase
{
public:
    ClxBase() {};
    virtual ~ClxBase() {};

virtual void DoSomething() { cout << "Do something in class ClxBase!" << endl; };
};

class ClxDerived : public ClxBase
{
public:
    ClxDerived() {};
    ~ClxDerived() { cout << "Output from the destructor of class ClxDerived!" << endl; };

void DoSomething() { cout << "Do something in class ClxDerived!" << endl; };
};
    代码

ClxBase *pTest = new ClxDerived;
pTest->DoSomething();
delete pTest;
    的输出结果是:

Do something in class ClxDerived!
Output from the destructor of class ClxDerived!
    这个很简单,非常好理解。
    但是,如果把类ClxBase析构函数前的virtual去掉,那输出结果就是下面的样子了:

Do something in class ClxDerived!
    也就是说,类ClxDerived的析构函数根本没有被调用!一般情况下类的析构函数里面都是释放内存资源,而析构函数不被调用的话就会造成内存泄漏。我想所有的C++程序员都知道这样的危险性。当然,如果在析构函数中做了其他工作的话,那你的所有努力也都是白费力气。
    所以,文章开头的那个问题的答案就是--这样做是为了当用一个基类的指针删除一个派生类的对象时,派生类的析构函数会被调用。
    当然,并不是要把所有类的析构函数都写成虚函数。因为当类里面有虚函数的时候,编译器会给类添加一个虚函数表,里面来存放虚函数指针,这样就会增加类的存储空间。所以,只有当一个类被用来作为基类的时候,才把析构函数写成虚函数。

转载于:https://www.cnblogs.com/LUO77/p/5907297.html

构造函数调用虚函数的问题相关推荐

  1. C++构造函数调用虚函数的后果

    #include <iostream>class cx { public:virtual void func() {std::cout << "func" ...

  2. 构造函数调用虚函数先从子类搜索同名函数

    1 class X 2 { 3 X() 4 { 5 System.out.println("x"); // 6 vir(44); //看到vir会先搜索子类中的vir是否存在,如果 ...

  3. C++构造函数和析构函数调用虚函数时都不会使用动态联编

    先看一个例子: #include <iostream> using namespace std;class A{ public:A() {show();}virtual void show ...

  4. Effective C++(9) 构造函数调用virtual函数会发生什么

    问题聚焦: 不要在构造函数和析构函数中调用virtual函数,因为这样的调用不会带来你预想的结果. 让我先来看一下在构造函数里调用一个virtual函数会发生什么结果 Demo class Trans ...

  5. C++构造函数与析构函数调用虚函数的注意事项

    虽然可以对虚函数进行实调用,但程序员编写虚函数的本意应该是实现动态联编.在构造函数中调用虚函数,函数的入口地址是在编译时静态确定的,并未实现虚调用.但是为什么在构造函数中调用虚函数,实际上没有发生动态 ...

  6. python构造函数调用成员函数_成员函数中的Python调用构造函数

    让我们以这个类为例,它正在扩展MySQLDB的connection对象.在class DBHandler(mysql.connections.Connection): def __init__(sel ...

  7. python构造函数调用成员函数_Python 子类构造函数调用

    super作用 如果子类(Puple)继承父类(Person)不做初始化,那么会自动继承父类(Person)属性name. 如果子类(Puple_Init)继承父类(Person)做了初始化,且不调用 ...

  8. java 析构函数_C++虚函数

    码字不易,欢迎给个赞! C++虚函数是多态性实现的重要方式,当某个虚函数通过指针或者引用调用时,编译器产生的代码直到运行时才能确定到底调用哪个版本的函数.被调用的函数是与绑定到指针或者引用上的对象的动 ...

  9. c++整理--虚函数

    一.虚函数是这么实现的 解析: 简单的说,虚函数是通过虚函数表实现的,那么什么是虚函数表呢? 事实上,如果一个类中含有虚函数表,则系统会为这个类分配一个指针成员指向一张虚函数表(vtbl),表中每一项 ...

最新文章

  1. canvars 画花
  2. 「SAP技术」MIGO 343 解冻物料库存的同时可以更改存储地点
  3. csgo卡程序关不掉_微信推QQ小程序,取代QQ?网友:这功能有用?
  4. 成功解决TypeError: map() got an unexpected keyword argument 'num_threads'
  5. python删除长目录_python中删除目录名两端
  6. 一款基于jQuery底部带缩略图的焦点图
  7. 【Python】SNMP的安装及Python的调用
  8. 【CCCC】L3-011 直捣黄龙 (30分),Dijkstra维护点权,节点数,路径条数等+路径打印
  9. DIY远程控制开关(tiny6410+LED+yeelink+curl)
  10. jsp和servlet面试题
  11. 罗辑回归,Logistic Regression(or sigmoid function)
  12. 香港资深艺人沈殿霞病逝 享年60岁(图)
  13. 逆波兰式求值 —Java
  14. YS_20190822_图像_Matlab_04
  15. 前端(以Vue为例)webpack打包后dist文件包如何部署到django后台中
  16. linux钉钉-使用playonlinux 可以使用视频会议
  17. 统计学习方法-感知机概括和补充
  18. BugkuCTF~Misc~WriteUp
  19. 电子商务网站建设策划书范例
  20. 半年从转行软件测试到产品经理

热门文章

  1. access9磅字体是多_第一套考试题
  2. 树莓派udev不能自动挂载_直播课:教你用树莓派实现智能商店的自动结账
  3. linux ppp拨号 socket,请问GPRS模块ppp拨号不成功是什么原因
  4. jQuery实现王者手风琴案例
  5. 小忆《记录博客一周年》
  6. SAP Query达到select * where 的效果 2011-04-29
  7. supermap iobect .net 7.1.2 图例的拆分
  8. EXC_BAD_ACCESS错误
  9. 使用Genymotion调试出现错误INSTALL_FAILED_CPU_ABI_INCOMPATI
  10. MECARD格式的电子名片简单介绍