析构函数virtual与非virtual区别

作为通常的原则,如果一个类定义了虚函数,那么它的析构函数就应当是virtual的。因为定义了虚函数则隐含着:这个类会被继承,并且会通过基类的指针指向子类对象,从而得到多态性。   这个类可能会被继承,并且会通过基类的指针指向子类对象”,因此基类的析构函数是否为虚将决定子类的对象是否被析构

示例代码:

#include <iostream.h>

struct A
{
    
virtual ~A() {cout<<"~A()\n";}
}
;

struct B: public A
{
    
~B() {cout<<"~B()\n";}
}
;

void main()
{
    A
* p = new B;
    delete p;
}


如果 A的析构函数不是virtual的,那么此时就不是先调用B的析构函数再调用A的析构函数。
Output:
~A(); 
如果A   的析构函数为virtual,则先~B(),再~A()  
Output:
~B();
~A();
       类如果会被派生的话,析构函数一般都应该定义为virtual的,主要不是防止内存泄露,而是为了正确的析构。如果是个封闭类(即不再被派生),就不要定义为virtual的。虚函数毕竟耗费较大的。

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

声明基类的析构函数为virtual并非总是为了防止memory   leak   另外这也只是作为一般的原则(基类中有虚函数则把其析构函数声明为virtual)。如果你的析构函数什么事也不作,从效果上来说,不声明为virtual也无妨





为什么C++析构函数前面有时需要 virtual

#include <iostream>

using namespace std;class Base{public:virtual ~Base() {cout<<"~B"<<endl;}
};class Derived:public Base{public:virtual ~Derived() {cout<<"~D"<<endl;}
};int main (){Base *b=new Derived;delete b;
}
 
复制代码

 以上代码执行结果是:

~D

~B

 

对于析构函数使用虚函数的解释,是这样的,因为是使用语句  Base *b=new Derived;来创建的对象b,如果,我们不把析构函数声明为虚函数,那么实际上,在对象生命周期结束时,调用的将只是基类Base的析构函数,而派生类Derived的析构函数将是不调用的,你可以试验一下,此时,只打印~B。而我们为了正确地释放对象,所以要将析构函数声明为虚函数,这时,基类和派生类的析构函数就都会调用了。


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/452389.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Python:字典列表字符串方法测试

测试的一些Python中的关于字典、列表、字符串的使用方法&#xff0c;放在这里备查。整个测试代码和说明如下&#xff1a; # -*- coding: utf-8 -*- """Python:函数中全是指针传递&#xff0c;而任何变量都是给予一个指针指向一个内存空间"""impo…

什么是确认测试

确认测试也称为验收测试&#xff0c;它的目标是验证软件的有效性。 通常&#xff0c;验证指的是保证软件正确地实现了某个特定要求的一系列活动&#xff1b;确认指的是为了保证软件确实满足了用户需求而进行的一系列活动。 软件有效性的一个简单定义是&#xff1a;如果软件的功…

Diango博客--17.统计各个分类和标签下的文章数

文章目录0.思路引导1.Model 回顾2.数据库数据聚合3.使用 Annotate4.在模板中引用新增的属性0.思路引导 在我们的博客侧边栏有分类列表和标签列表&#xff0c;显示博客已有的全部文章分类。现在想在分类名和标签名后显示该分类或者标签下有多少篇文章&#xff0c;该怎么做呢&am…

HTTP协议中request报文请求方法和状态响应码

一个HTTP请求报文由4部分组成&#xff1a; 请求行&#xff08;request line&#xff09;请求头部&#xff08;header&#xff09;空行请求数据下图给出了请求报文的一般格式&#xff1a; 请求行中包括了请求方法&#xff0c;常见的请求方法有&#xff1a; GET&#xff1a;从服务…

计算机无法安装64位操作系统,为什么我的win7旗舰版service Pack 1 64位操作系统 无法安装(KB2670838) 这个更新...

您好&#xff01;我了解到您遇到关于这边的问题请问无法安装是否出现了什么错误代码提示呢&#xff1f;请参考以下的步骤解决按WindowsR打开cmd里使用下面的命令关闭相关的一些服务&#xff1a;net stop wuauservnet stop cryptSvcnet stop bitsnet stop msiserver完成后&#…

bmon:一个强大的网络带宽监视和调试工具

bmon 是类 Unix 系统中一个基于文本&#xff0c;简单但非常强大的 网络监视和调试工具&#xff0c;它能抓取网络相关统计信息并把它们以用户友好的格式展现出来。它是一个可靠高效的带宽监视和网速估测工具。 它能使用各种输入模块读取输入&#xff0c;并以各种输出模式显示输出…

函数的调用规则(__cdecl,__stdcall,__fastcall,__pascal)

关于函数的调用规则&#xff08;调用约定&#xff09;&#xff0c;大多数时候是不需要了解的&#xff0c;但是如果需要跨语言的编程&#xff0c;比如VC写的dll要delphi调用&#xff0c;则需要了解。 microsoft的vc默认的是__cdecl方式&#xff0c;而windows API则是__stdcall&a…

Linux 下的/usr/bin /usr/sbin /usr/local/bin /usr/local/sbin区别

1、/bin 是所有用户都可以访问并执行的可执行程序。包括超级用户及一般用户。 供所有用户&#xff08;包括root用户和一般用户&#xff09;使用的基本命令&#xff0c;主要有cat,chmod,date,cp,bash等等常用的命令。 2、/usr/bin&#xff1a;系统预装的可执行程序&#xff0c;…

alpha测试和betal测试

如果一个软件是为许多客户开发的&#xff08;例如&#xff0c;向大众公开出售的盒装软件产品&#xff09;&#xff0c;那么绝大多数软件开发商都使用被称为Alpha测试和Beta测试的过程&#xff0c;来发现那些看起来只有最终用户才能发现的错误。 Alpha测试由用户在开发者的场所进…

计算机d盘无法格式化,四种方法解决D盘无法格式化问题

不少朋友系统出现故障&#xff0c;几乎都是选择重装系统的方法来解决问题。系统重装后&#xff0c;不少朋友觉得D盘没有什么重要的东西&#xff0c;就想将其格式化&#xff0c;可是系统出现windows无法格式该驱动器的提示&#xff0c;这是怎么回事呢&#xff1f;D盘无法格式化要…

sqlserver视图

作用 ①简化了操作&#xff0c;把经常使用的数据定义为视图。 ②安全性&#xff0c;用户只能查询和修改能看到的数据。 ③逻辑上的独立性&#xff0c;屏蔽了真实表的结构带来的影响。 对视图的修改&#xff1a;单表视图一般用于查询和修改&#xff0c;会改变基本表的数据&#…

非root用户sudo_ssh免密钥

非root用户sudo_ssh免密钥 目标&#xff1a;从服务器上ssh登陆后sudo免密钥执行相应的命令 环境介绍&#xff1a; 192.168.65.128 my1-222 192.168.65.129 my2-223 192.168.65.130 web224# 步骤一&#xff1a; # 每个节点执行(不是必须&#xff0c;但是建议这样做) cat …

复旦大学和吉大计算机考研选哪个,2016复旦大学VS吉林大学 基于排名角度的比较?...

复旦大学好还是吉林大学好首先&#xff0c;2016复旦大学好还是吉林大学好是近日问得较多的问题之一&#xff0c;小伙伴们有的从吉林大学和复旦大学的地理位置优势角度进行分析&#xff0c;有的从吉林大学和复旦大学的强势专业角度进行PK&#xff0c;有的甚至从吉林大学和复旦大…

Diango博客--18.使用 Fabric 自动化部署 Django 项目

文章目录1.本地安装 Fabric2.部署过程回顾3.完善项目配置4.修改 BASE_DIR 配置项5.设置 Supervisor 环境变量6.编写 Fabric 脚本7.执行 Fabric 自动部署脚本1.本地安装 Fabric $ pipenv install fabric --dev 报错&#xff1a; An error occurred while installing django-pure…

白盒测试详解

通常把测试数据和预期的输出结果称为测试用例。 &#xff08;一&#xff09;逻辑覆盖 是对一系列测试过程的总称&#xff0c;这组测试过程逐渐进行越来越完整的通路测试。 1.语句覆盖 语句覆盖的含义是&#xff0c;选择足够多的测试数据&#xff0c;使被测程序中每个语句至少…

git 的安装以及使用:是一个开源的分布式版本控制系统,可以对项目进行版本管理。 早期是linux之父用来管理linux系统源代码的(linux是和windows一样操作系统 开源免费的操作...

## 总结 - 学会使用基本的git命令 管理源代码- 学会去github创建仓库 并将代码上传到github的仓库 (有待完成 回家有网再push)- 了解本地的.git和服务器github的.git的关系 是两个仓库 一个是本地 一个是服务器 需要使用一句命令来关联 git remote add origin 远端的.git的地址…

自断前程,未来80%IT工作将实现自动化

技术人员革了自己的命&#xff1f; 在上周的Structure大会上&#xff0c;硅谷著名风险投资人、亿万富翁唯诺德称未来80%的IT工作都将被AI系统所替代。不过&#xff0c;唯诺德好像并不担心&#xff0c;相反他补充了一句“我觉得很兴奋。”唯诺德表示自己并非危言耸听&#xff0c…

2013计算机二级试题,2013全国计算机二级上机考试试题46-100套试题

*第46 套上机考试试题一、基本操作题**请根据以下各小题的要求设计Visual Basic 应用程序(包括界面和代码)。(1)在名称为Form1、标题为“框架练习”的窗体上*画一个名称为Frame1、标题为“字体”的框架控件&#xff1b;在框架中画两个单选按钮&#xff0c;名称分别为Option1、O…

黑盒测试详解

黑盒测试着重测试软件功能。黑盒测试并不能取代白盒测试&#xff0c;它是与白盒测试互补的测试方法&#xff0c;它很可能发现白盒测试不易发现的其他类型的错误。白盒测试在测试过程的早期阶段进行&#xff0c;而黑盒测试主要用于测试过程的后期。 黑盒测试力图发现下述类型的…

linux中rpm、yum、apt-get的关系

Linux中yum和apt-get用法及区别 一般来说著名的linux系统基本上分两大类&#xff1a; 1.RedHat系列&#xff1a;Redhat、Centos、Fedora等 2.Debian系列&#xff1a;Debian、Ubuntu等 RedHat 系列 1 常见的安装包格式 rpm包,安装rpm包的命令是“rpm -参数” 2 包管理工具 y…