• 条款07:为多态基类声明virtual析构函数


    1、为什么要给多态设计带多态性质的基类声明virtual析构函数?

    考虑一个场景:有一个基类指针指向了一个派生类对象,而这个派生类对象创建在堆内存上。当通过delete关键字回收这块内存时,delete的是基类的指针。此时,就会发生一种怪异的现象:该派生类的基类部分被回收了,但是派生类部分没有被回收。即:导致了内存的泄露。实际上,此时只执行了基类的析构函数,没有执行派生类的析构函数。因此,即使该对象没有在堆内存上创建,但是如果析构函数中函数某些逻辑代码时,也为导致不明确行为的发生。这时虽然没有发生内存泄露,但是代码却出错了。因此,多态基类声明virtual析构函数。

    2、为什么不作为多态用途使用的类的析构函数一定不能加virtual?

    有下面两个原因:

    • 浪费内存
    • 降低了移植性

    将析构函数声明为virtual,则代表这个类作为多态使用。而作为多态使用的类是有一定内存消耗的:多态类的实例化对象内部都有一个指针,指向虚函数表。而每一个作为多态使用的类都有一个虚函数表,用来在运行程序时确定执行哪一个函数。当将一个不作为多态使用的类的析构函数声明为virtual时,首先会增加这些内存。其次,从语言移植性来讲,由于破坏了类对象的原本的存储的结构,C++代码向C或其它代码的一致性也降低了。

    3、欲将一个类设计为抽象类,却没有合适可用的纯虚函数时的一个技巧

    首先抽象类一定是作为基类使用的,而抽象类一定会作为多态使用。因此可以将其析构函数声明为纯虚函数。但是这里有一个注意的点,即:需要为该纯虚函数提供一份定义。

    class AWOV{
    	virtual ~AWOV()=0;
    }
    AWOV::~AWOV(){}
    

    4、避免继承标准库中不作为多态使用的类

    标准库中不作为多态使用的类(带有non-virtual的类):
    所有容器类(vector、set等等)、string这些类设计出来不作为基类使用,更不是作为多态使用。某些类设计出来作为基类使用,但是不作为多态使用。
    使用有上述这些类派生出来的类可能导致意想不到的情况。

  • 相关阅读:
    测试数据生成利器
    9.22“月饼杯”递归算法欢乐赛测试报告总结
    lemon评测软件配置使用方法
    1200:分解因数
    大犇博客
    C++ |递归原理与构造技巧
    2018.9.8信息奥赛集训评测报告总结
    1195 判断整除
    计算机图形学初步
    AcWing
  • 原文地址:https://www.cnblogs.com/lasnitch/p/12764214.html
Copyright © 2020-2023  润新知