析构函数中的virtual是否必要?
我们经常听到建议要把构造函数不能为虚,析构函数最好为虚,这是为什么?
如下例子:
// 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是否必要?相关推荐
- 在构造函数/析构函数中调用virtual函数带来的影响
在构造函数/析构函数中调用virtual函数,那么调用的一定是本类中的virtual函数. 先看一段代码: #include<iostream>class Base { public:Ba ...
- C++经验(四)-- 基类构造函数和析构函数中调用virtual虚函数?
class Base {public:Base();virtual void oneFunction() = 0;... };Base::Base() {...oneFunction(); }clas ...
- Effective C++条款09:绝不在构造和析构过程中调用virtual函数
Effective C++条款09:绝不在构造和析构过程中调用virtual函数(Never call virtual functions during construction or destruc ...
- effective c++:virtual函数在构造函数和析构函数中的注意事项
effective c++:virtual函数在构造函数和析构函数中的注意事项 如不使用自动生成函数要明确拒绝 对于一个类,如果你没有声明,c++会自动生成一个构造函数,一个析构函数,一个copy构造 ...
- C++中最好不要在构造函数和析构函数中调用虚函数!!!
1.最好不要在基类和派生类的构造和析构函数中调用虚函数,不会出现多态性 实例如下: #include "iostream"using namespace std;class Bas ...
- 第8集析构函数中抛出的异常
前两篇文章讨论了对象在构造过程中(构造函数)和运行过程中(成员函数)出现异常时的处理情况,本文将讨论最后一种情况,当异常发生在对象的析构销毁过程中时,又会有什么不同呢?主人公阿愚在此可以非常有把握地告 ...
- 构造函数和析构函数中抛出异常
文章目录 1 构造函数中抛出异常 2 析构函数中的异常 1 构造函数中抛出异常 如果构造函数中抛出异常会发生什么情况? 构造函数中抛出异常: 构造过程立即停止. 当前对象无法生成. 析构函数不会被调用 ...
- 条款9:不要在构造和析构过程中调用virtual函数
如下是一个股票交易的例子: 1 class Transaction // 交易的基类 2 { 3 public: 4 Transaction(); 5 virtual void logTransact ...
- C++学习笔记-----不要在构造函数和析构函数中调用虚函数
考虑下面的程序: #include <iostream> using namespace std;class Base { public:Base() { cout << &q ...
- C++中最好不要在构造函数和析构函数中调用虚函数
1.最好不要在基类和派生类的构造和析构函数中调用虚函数,不会出现多态性 实例如下: #include "iostream"using namespace std;class Bas ...
最新文章
- Linux 中echo格式控制、重定向 、管道 | 简介
- OpenGL ES 3.0 基础知识
- fou循环 php 剩余次数_php for 循环语句使用方法详细说明
- 在word中,整篇文章想要在每一章另起一页
- mysql net 指令_MySQL命令
- Shell 脚本加密工具-shc
- 菜鸟Python实战-05爬虫之爬取视频
- 笔记本计算机怎么进入安全模式启动,笔记本怎么进入安全模式
【使用步骤】...
- 小酌重构系列[12]——去除上帝类
- 授权公众号第三方平台和开发者模式冲突吗?
- UEBA对抗威胁之“健康就是财富”!
- 招商大师与星范集团等医美龙头达成战略合作 从提业绩到建标杆
- 替代DRV8825的打印机/扫描仪驱动芯片TMI8420
- 2021-05-18 人头检测 version-slim(主干精简速度略快),version-RFB(加入了修改后的RFB模块,精度更高)
- MSM8974 TP驱动流程
- 夺宝网站服务器配置,【合区公告】“夺宝奇兵”“决战昆仑”服务器数据互通操作...
- 为什么现在有些研究生想退学?
- t30什么时间升级鸿蒙,性能升级富士旗舰无反X-T3新固件发布
- GDB使用手册(四)、GDB命令
- 减少ipdata1的方法
热门文章
- 二手机床:中国高端机床装备制造列入战略性产业
- 计算机辅助与设计专业,计算机辅助设计与制造专业怎么样?
- 怎样对计算机窗口进行截图,Windows10:如何对计算机屏幕上的内容进行屏幕截图...
- 用VS2015编译pjsip的工程pjproject-vs14
- 1546: 回形取数
- python输入人名对话_对话框中的用户输入
- 最长公共子序列(输出公共序列)
- azkaban 入门简介
- cpu win10 安装yolo_Win10 超详细 0基础 搭建YOLOV5教程【环境搭建篇】
- 一秒钟世界上会发生多少事_再多涂改,人性也总会醒来,也总会主动去追寻那一秒钟...