A* a=new B ,会不会产生内存泄露了,露了B-A的部分?

A* a=new B ,delete a;会不会产生内存泄露了,露了B-A的部分。其中B为A的子类

析构函数在下边3种情况时被调用:
1.对象生命周期结束,被销毁时;
2.delete指向对象的指针时,或delete指向对象的基类类型指针,而其基类虚构函数是虚函数时;
3.对象i是对象o的成员,o的析构函数被调用时,对象i的析构函数也被调用。

情况1请看下边代码:
#include<iostream.h>
class A
{
 public:
 A()
 {
  cout<<"constructing A"<<endl;
 } 
 ~A()
 {
  cout<<"destructing A"<<endl;
 }
 private:
 int a;
};
class B: public A
{
 public:
 B()
 {
  cout<<"constructing B"<<endl;
 }
 ~B()
 {
  cout<<"destructing B"<<endl;
 }
 private:
 int b;
};

void main()
{
 B b;
}

运行结果为:

constructing A
constructing B
destructing B
destructing A

上述代码还说明了一件事:析构函数的调用顺序与构造函数的调用顺序相反。

情况2则正好说明了为什么基类应该把析构函数声明为虚函数,请先看下边的例子:

#include<iostream.h>
class A
{
 public:
 A()
 {
  cout<<"constructing A"<<endl;
 } 
 ~A()
 {
  cout<<"destructing A"<<endl;
 }
 private:
 int a;
};
class B: public A
{
 public:
 B()
 {
  cout<<"constructing B"<<endl;
 }
 ~B()
 {
  cout<<"destructing B"<<endl;
 }
 private:
 int b;
};

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

运行结果为:

constructing A
constructing B
destructing A

若将class A中的析构函数声明为虚函数,运行结果将变成:

constructing A
constructing B
destructing B
destructing A

由此还可以看出虚函数还是多态的基础,才c++中没有虚函数就无法实现多态。因为不声明成虚函数就不能“推迟联编”,所以不能实现多态。这点上和Java不同,java总是“推迟联编”的,所以也剩了这些麻烦。

扯远了,再看情况3,通过下边代码表示:
#include<iostream.h>
class A
{
 public:
 A()
 {
  cout<<"constructing A"<<endl;
 }
 ~A()
 {
  cout<<"destructing A"<<endl;
 }
 private:
 int a;
};

class C
{
 public:
 C()
 {
  cout<<"constructing C"<<endl;
 }
 ~C()
 {
  cout<<"destructing C"<<endl;
 }
 private:
  int c;
};

class B: public A
{
 public:
 B()
 {
  cout<<"constructing B"<<endl;
 }
 ~B()
 {
  cout<<"destructing B"<<endl;
 }
 private:
 int b;
 C c;
};

void main()
{
 B b;
}

运行结果为:

constructing A
constructing C
constructing B
destructing B
destructing C
destructing A

b的析构函数调用之后,又调用了b的成员c的析构函数,同时再次验证了析构函数的调用顺序与构造函数的调用顺序相反。

若将上边的代码中的main()函数内容改成

 A* a = new B;
 delete a;
 
由情况2我们知道,这将不会调用class B的析构函数不会被调用,所以class C的析构函数也不会被调用。
正如我们想的,运行结果为:

constructing A
constructing C
constructing B
destructing A

俗话说温故而知新,我却不想做什么师,只是希望能够和大家分享一下对析构函数和虚析构函数的更深的认识。以上代码在VC++6.0上测试通过,如有疏漏或错误的认识请大家指正:

转载于:https://www.cnblogs.com/dobben/p/7440913.html

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

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

相关文章

spring 第一天:1015

对象加强的三种方法&#xff1a;1/继承2/装饰着模式3/动态调用 2&#xff1a;装饰着模式&#xff1a;就是就是1-先建一个基类 &#xff0c;如咖啡类 。味道很苦2- 再建一个类配料类 也就是说是所欲配料种类的父类。然后写多配料子类个子类继承配料类&#xff0c;。3-子类三个步…

java public 继承_java继承问题

代码&#xff1a;父类&#xff1a;public class Father {public Father() {System.out.println("基类构造函数{");show();new a();System.out.println("}");}public void show() {System.out.println("基类----show");}public class a {public a…

BZOJ 1662: [Usaco2006 Nov]Round Numbers 圆环数(数位DP+恶心细节)

BZOJ 1662: [Usaco2006 Nov]Round Numbers 圆环数 Time Limit: 5 Sec Memory Limit: 64 MBDescription 正如你所知&#xff0c;奶牛们没有手指以至于不能玩“石头剪刀布”来任意地决定例如谁先挤奶的顺序。她们甚至也不能通过仍硬币的方式。 所以她们通过"round number&q…

Optimizing Code with GCC

现在的编译器越来越聪明&#xff0c;功能越来越强&#xff0c;从简单的函数内联&#xff0c;到复杂的寄存器分析&#xff0c;一系列代码革命使程序运行得越来越快。大多数时候&#xff0c;更快比更小重要&#xff0c;因为磁盘空间和内存都变得便宜了。但是在嵌入式系统里&#…

QTP的那些事--操作excel的函数

1: QTP Excel函数 操作EXCEL 数据表格 表单 编辑EXCEL 工作表 2: Dim ExcelApp As Excel.Application 3: Dim excelSheet As Excel.worksheet 4: Dim excelBook As Excel.workbook 5: Dim fso As scrīpting.FileSystemObject 6: 7: ******************…

java-生产者消费者模式

经常会有公司叫我们手撕代码&#xff0c;比如网易&#xff0c;阿里&#xff0c;那我们是不是该掌握下呢。下面这段代码来自《现代操作系统》进程与线程P49页。 public class ProducerConsumer {public ProducerConsumer() { }private static final int N 100;static Producer …

yum查询已经安装mysql_通过yum安装mysql

在linux中安装数据库首选MySQL&#xff0c;Mysql数据库的第一个版本就是发行在Linux系统上&#xff0c;其他选择还可以有postgreSQL&#xff0c;oracle等在Linux上安装mysql数据库&#xff0c;我们可以去其官网上下载mysql数据库的rpm包&#xff0c;http://dev.mysql.com/downl…

koa2-cookie-session

node.js的path.extname方法使用   由于该方法属于path模块&#xff0c;使用前需要引入path模块&#xff08;var path require(“path”) &#xff09;   接收参数&#xff1a;   p path 路径 path.extname(index.html)// returns.htmlpath.extname(index.)// returns.pat…

从程序员角度看ELF

从程序员角度看ELF原文:《 ELF:From The Programmers Perspective》作者&#xff1a;Hongjiu Lu <mailto: hjlnynexst.com>NYNEX Science & Technology, Inc. 500 Westchester Avenue White Plains, NY 10604, USA 翻译&#xff1a;alert7 <mailto: alert721cn.co…

JAVA命令符找不到符号_[转]Java命令行编译文件时出现的错误,找不到符号或软件包不存在等...

标签(空格分隔)&#xff1a; Javajavascript习惯了eclipse的自动编译&#xff0c;Java命令行编译、执行文件只会最基础的部分&#xff0c;就是对单文件的编译和执行&#xff0c;并且不包含任何外部JAR包。但有时候你还非得用命令行&#xff0c;会碰到一些问题&#xff0c;博主这…

C#中POST数据和接收的几种方式

POST方式提交数据&#xff0c;一种众所周知的方式&#xff1a; html页面中使用form表单提交&#xff0c;接收方式&#xff0c;使用Request.Form[""]或Request.QueryString[""]来获取。 这里介绍另外一种POST方式和接收方式&#xff0c;就是将整个数据作为加…

java自动注入注解_Spring自动注解标签@Autowired不能注入xml配置的bean吗?

该楼层疑似违规已被系统折叠 隐藏此楼查看此楼配置service的xmlservice代码public class LoginServiceImpl extends BaseDaoServiceImpl implements LoginService {Overridepublic Map queryByUserName(String userName){IDao iDao super.getAppDao();return (Map)iDao.queryF…

一卡通vip充值消费线上oracle库服务器故障排查过程

上图是oracle体系总架构图今天突然公司所有终端pos机不能刷卡消费&#xff0c;财务室不能充值&#xff0c;一下很多电话打过来了&#xff0c;第一反应肯定数据库出问题了&#xff0c;登陆到数据库服务器&#xff0c;果然sqlplus连进去后就不断提示要求输入用户名&#xff0c;弹…

最详细的Linux下C编程

gcc 目 录 1. gcc 1. makefile写法 2. gcc_egcs使用 3. gdb使用 4. gcc常用选项对代码的影响 1. 一般情况 2. -O 编译选项 3. -O2 编译选项 4. -fomit-frame-pointer 编译选项 5. -fomit-frame-pointer…

sqlserver 存储过程 增加

CREATE PROCEDURE [dbo].[InsertMessage]( strTable varchar(50), --表名 strValues nvarchar(1000), --要插入的数据&#xff08;用英文逗号分隔&#xff09;,如果是字符串类型&#xff0c;需加单引号 only_field varchar(20)NULL, --唯一性字段(列名) only_valu…

java开发计算机考试服务器_2011计算机二级JAVA编程:取得服务器当前的各种具体时间...

取得服务器当前的各种具体时间/*** 取得服务器当前的各种具体时间* 回车&#xff1a;日期时间*/import java.util.*;public class GetNowDate{Calendar calendar null;public GetNowDate(){calendar Calendar.getInstance();calendar.setTime(new Date());}public int getYea…

(cljs/run-at (JSVM. :all) 细说函数)

前言 作为一门函数式编程语言&#xff0c;深入了解函数的定义和使用自然是十分重要的事情&#xff0c;下面我们一起来学习吧&#xff01; 3种基础定义方法 defn 定义语法 (defn name [params*]exprs*) 示例 (defn tap [ns x](println ns x)x) fn 定义语法 (fn name? [params*]…

Request的getHeader()和getParameter()的区别

区别是&#xff1a;一个是获得HTTP头信息,一个是获得表单参数值。转载于:https://www.cnblogs.com/pxffly/p/7460514.html

gcc中的内嵌汇编语言(Intel i386平台)

gcc中的内嵌汇编语言&#xff08;Inteli386平台&#xff09; 一.声明 虽然Linux的核心代码大部分是用C语言编写的&#xff0c;但是不可避免的其中还是有一部分是用汇编语言写成的。有些汇编语言代码是直接写在汇编源程序中的&#xff0c;特别是Linux的启动代码部分&#xff1b…

数据库学习,树形结构的数据库表Schema设计方案

2019独角兽企业重金招聘Python工程师标准>>> 程序设计过程中&#xff0c;我们常常用树形结构来表征某些数据的关联关系&#xff0c;如企业上下级部门、栏目结构、商品分类等等&#xff0c;通常而言&#xff0c;这些树状结构需要借助于数据库完成持久化。然而目前的各…