我们经常听到建议要把构造函数不能为虚,析构函数最好为虚,这是为什么?

如下例子:

// pvtable1.cpp : 定义控制台应用程序的入口点。


#include "stdafx.h"#include <iostream>using namespace std;class Base1 {public:Base1(){ cout << "Base1::Base1()" << endl; }~Base1(){ cout << "Base1::~Base1()" << endl; }virtual void f() { cout << "Base1::f" << endl; }virtual void g() { cout << "Base1::g" << endl; }virtual void h() { cout << "Base1::h" << endl; }};class Base2 {public:Base2(){ cout << "Base2::Base2()" << endl; }~Base2(){ cout << "Base2::~Base2()" << endl; }virtual void f() { cout << "Base2::f" << endl; }virtual void g() { cout << "Base2::g" << endl; }virtual void h() { cout << "Base2::h" << endl; }};class Base3 {public:Base3(){ cout << "Base3::Base3()" << endl; }~Base3(){ cout << "Base3::~Base3()" << endl; }virtual void f() { cout << "Base3::f" << endl; }virtual void g() { cout << "Base3::g" << endl; }virtual void h() { cout << "Base3::h" << endl; }};class Derive : public Base1, public Base2, public Base3 {public:Derive(){ cout << "Derive::Derive()" << endl; }~Derive(){ cout << "Derive::~Derive()" << endl; }virtual void f() { cout << "Derive::f" << endl; }virtual void g1() { cout << "Derive::g1" << endl; }};
int doIt2()
{Base1 *pBase1 = new Derive();delete pBase1;return 0;}int _tmain(int argc, _TCHAR* argv[])
{    doIt2();return 0;
}

当使用一个多重继承的时候,使用父类的指针删除子类的时候,发现了不能正常析构的情况,执行结果如下:

如果在将父类的析构函数定义为虚函数,便正常了

一个类中将所有的成员函数都尽可能地设置为虚函数总是有益的。虽然会增大开销

下面是设置虚函数的注意事项:

1、只有类的成员函数才能声明为虚函数。

2、静态成员函数不能使虚函数,因为它不受限于某个对象。

3、内联函数不能使虚函数。

4、构造函数不能是虚函数。

不用virtual 的几种情况:
1、作为非公有基类。仅作为 private base class 使用的 class 不需要使用虚拟析构函数
2、不作为接口使用的基类。
3. 如果你可以保证这个类不被public继承(private/protected继承的话,在非friend函数/类中就无法用基类指针指向派生类了)
4. 如果它的所有派生类(包括派生类的派生类)的析构函数都是trivial的(这里的trivial指的是在程序员的层次什么事也不做)
5. 如果不需要用基类的指针指向派生类的对象
在这五种情况下,不把析构函数声明为virtual都是可以的,何况效率会高一些——但前提是你得保证前提的成立——不过这些保证常常是很难100%的:谁能保证别人在派生你的类的时候,析构函数是trivial的,或者别人不用你提供的基类的指针指向派生类对象?这些常常是很难得到保证的。

析构函数中的virtual是否必要?相关推荐

  1. 在构造函数/析构函数中调用virtual函数带来的影响

    在构造函数/析构函数中调用virtual函数,那么调用的一定是本类中的virtual函数. 先看一段代码: #include<iostream>class Base { public:Ba ...

  2. C++经验(四)-- 基类构造函数和析构函数中调用virtual虚函数?

    class Base {public:Base();virtual void oneFunction() = 0;... };Base::Base() {...oneFunction(); }clas ...

  3. Effective C++条款09:绝不在构造和析构过程中调用virtual函数

    Effective C++条款09:绝不在构造和析构过程中调用virtual函数(Never call virtual functions during construction or destruc ...

  4. effective c++:virtual函数在构造函数和析构函数中的注意事项

    effective c++:virtual函数在构造函数和析构函数中的注意事项 如不使用自动生成函数要明确拒绝 对于一个类,如果你没有声明,c++会自动生成一个构造函数,一个析构函数,一个copy构造 ...

  5. C++中最好不要在构造函数和析构函数中调用虚函数!!!

    1.最好不要在基类和派生类的构造和析构函数中调用虚函数,不会出现多态性 实例如下: #include "iostream"using namespace std;class Bas ...

  6. 第8集析构函数中抛出的异常

    前两篇文章讨论了对象在构造过程中(构造函数)和运行过程中(成员函数)出现异常时的处理情况,本文将讨论最后一种情况,当异常发生在对象的析构销毁过程中时,又会有什么不同呢?主人公阿愚在此可以非常有把握地告 ...

  7. 构造函数和析构函数中抛出异常

    文章目录 1 构造函数中抛出异常 2 析构函数中的异常 1 构造函数中抛出异常 如果构造函数中抛出异常会发生什么情况? 构造函数中抛出异常: 构造过程立即停止. 当前对象无法生成. 析构函数不会被调用 ...

  8. 条款9:不要在构造和析构过程中调用virtual函数

    如下是一个股票交易的例子: 1 class Transaction // 交易的基类 2 { 3 public: 4 Transaction(); 5 virtual void logTransact ...

  9. C++学习笔记-----不要在构造函数和析构函数中调用虚函数

    考虑下面的程序: #include <iostream> using namespace std;class Base { public:Base() { cout << &q ...

  10. C++中最好不要在构造函数和析构函数中调用虚函数

    1.最好不要在基类和派生类的构造和析构函数中调用虚函数,不会出现多态性 实例如下: #include "iostream"using namespace std;class Bas ...

最新文章

  1. Linux 中echo格式控制、重定向 、管道 | 简介
  2. OpenGL ES 3.0 基础知识
  3. fou循环 php 剩余次数_php for 循环语句使用方法详细说明
  4. 在word中,整篇文章想要在每一章另起一页
  5. mysql net 指令_MySQL命令
  6. Shell 脚本加密工具-shc
  7. 菜鸟Python实战-05爬虫之爬取视频
  8. 笔记本计算机怎么进入安全模式启动,笔记本怎么进入安全模式 【使用步骤】...
  9. 小酌重构系列[12]——去除上帝类
  10. 授权公众号第三方平台和开发者模式冲突吗?
  11. UEBA对抗威胁之“健康就是财富”!
  12. 招商大师与星范集团等医美龙头达成战略合作 从提业绩到建标杆
  13. 替代DRV8825的打印机/扫描仪驱动芯片TMI8420
  14. 2021-05-18 人头检测 version-slim(主干精简速度略快),version-RFB(加入了修改后的RFB模块,精度更高)
  15. MSM8974 TP驱动流程
  16. 夺宝网站服务器配置,【合区公告】“夺宝奇兵”“决战昆仑”服务器数据互通操作...
  17. 为什么现在有些研究生想退学?
  18. t30什么时间升级鸿蒙,性能升级富士旗舰无反X-T3新固件发布
  19. GDB使用手册(四)、GDB命令
  20. 减少ipdata1的方法

热门文章

  1. 二手机床:中国高端机床装备制造列入战略性产业
  2. 计算机辅助与设计专业,计算机辅助设计与制造专业怎么样?
  3. 怎样对计算机窗口进行截图,Windows10:如何对计算机屏幕上的内容进行屏幕截图...
  4. 用VS2015编译pjsip的工程pjproject-vs14
  5. 1546: 回形取数
  6. python输入人名对话_对话框中的用户输入
  7. 最长公共子序列(输出公共序列)
  8. azkaban 入门简介
  9. cpu win10 安装yolo_Win10 超详细 0基础 搭建YOLOV5教程【环境搭建篇】
  10. 一秒钟世界上会发生多少事_再多涂改,人性也总会醒来,也总会主动去追寻那一秒钟...