zoukankan      html  css  js  c++  java
  • 条款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这些类设计出来不作为基类使用,更不是作为多态使用。某些类设计出来作为基类使用,但是不作为多态使用。
    使用有上述这些类派生出来的类可能导致意想不到的情况。

  • 相关阅读:
    在 springboot 中如何整合 shiro 应用 ?
    HTTP协议入门基础
    Git进阶--你可能不知道的很好用Git功能
    CentOS Linux最常用命令及快捷键整理
    Linux 下的 Docker 安装与使用
    Linux下强大的查找命令find 用法和常见用例
    如何使用find命令在Linux中查找文件
    Linux常用基础命令整理:关机命令、查看目录下文件命令等
    linux 时间同步的2种方法
    什么是跨域?
  • 原文地址:https://www.cnblogs.com/lasnitch/p/12764214.html
Copyright © 2011-2022 走看看