C++中继承 声明基类析构函数为虚函数作用,单继承和多继承关系的内存分布
1,基类析构函数不为虚函数
#include "pch.h"
#include <iostream> class CBase
{
public:
CBase() {
m_one = ;
printf("this is CBase construct\n");
}
~CBase() {
printf("this is ~CBase deconstruct\n");
} void setNumOne(int n)
{
m_one = n;
}
int getNumOne()
{
return m_one;
}
private:
int m_one;
}; class CDrived:public CBase
{
public:
CDrived() {
m_two = ;
printf("this is CDrived construct\n");
}
~CDrived() {
printf("this is ~CDrived deconstruct\n");
} void setNumTwo(int n)
{
m_two = n;
}
int getNumTwo()
{
return m_two;
}
private:
int m_two;
}; int main()
{
CBase *p = new CDrived;
delete p;
std::cout << "Hello World!\n";
}
输出:
this is CBase construct
this is CDrived construct
this is ~CBase deconstruct
Hello World!
可以发现继承类析构函数没有调用,若继承类中有一些资源需要释放,则不能释放,故需要将基类析构函数声明为虚函数。
#include "pch.h"
#include <iostream> class CBase
{
public:
CBase() {
m_one = ;
printf("this is CBase construct\n");
}
virtual ~CBase() {
printf("this is ~CBase deconstruct\n");
} void setNumOne(int n)
{
m_one = n;
}
int getNumOne()
{
return m_one;
}
private:
int m_one;
}; class CDrived:public CBase
{
public:
CDrived() {
m_two = ;
printf("this is CDrived construct\n");
}
~CDrived() {
printf("this is ~CDrived deconstruct\n");
} void setNumTwo(int n)
{
m_two = n;
}
int getNumTwo()
{
return m_two;
}
private:
int m_two;
}; int main()
{
CBase *p = new CDrived;
delete p;
std::cout << "Hello World!\n";
}
输出:
this is CBase construct
this is CDrived construct
this is ~CDrived deconstruct
this is ~CBase deconstruct
Hello World!
2,
#include "pch.h"
#include <iostream> class CBase
{
public:
CBase() {
m_one = ;
printf("this is CBase construct\n");
}
virtual ~CBase() {
printf("this is ~CBase deconstruct\n");
} virtual void setNumOne(int n)
{
m_one = n;
}
virtual int getNumOne()
{
return m_one;
}
private:
int m_one;
}; class CDrived:public CBase
{
public:
CDrived() {
m_two = ;
printf("this is CDrived construct\n");
}
~CDrived() {
printf("this is ~CDrived deconstruct\n");
} void setNumTwo(int n)
{
m_two = n;
}
int getNumTwo()
{
return m_two;
}
private:
int m_two;
}; int main()
{
CDrived *p = new CDrived;
printf("sizeof(CDrived) = %d\n", sizeof(CDrived)); //
delete p;
std::cout << "Hello World!\n";
}
3,多继承
单继承只有一个虚表指针,而多继承往往有多个
#include "pch.h"
#include <iostream> class CFather
{
public:
CFather() { }
~CFather() { } virtual void setTall(int tall)
{
m_tall = tall;
} private:
int m_tall;
}; class CMother
{
public:
CMother() { }
~CMother() { } virtual void setWeight(int weight)
{
m_weight = weight;
} private:
int m_weight;
}; class CSon:public CFather,public CMother
{
public:
CSon() { }
~CSon() { } virtual void setAge(int age) // 地址存放在第一个虚表指针后面
{
m_age = age;
} private:
int m_age;
}; int main()
{
CSon cSon;
cSon.setAge();
printf("sizeof(CSon) = %d\n", sizeof(CSon)); // 20
std::cout << "Hello World!\n";
}
C++中继承 声明基类析构函数为虚函数作用,单继承和多继承关系的内存分布的更多相关文章
- C++中的类继承(2)派生类的默认成员函数
在继承关系里面, 在派生类中如果没有显示定义这六个成员 函数, 编译系统则会默认合成这六个默认的成员函数. 构造函数. 调用关系先看一段代码: class Base { public : Base() ...
- C++中为什么构造函数不能是虚函数,析构函数是虚函数
一, 什么是虚函数? 简单地说,那些被virtual关键字修饰的成员函数,就是虚函数.虚函数的作用,用专业术语来解释就是实现多态性(Polymorphism),多态性是将接口与实现进行分离:用形象的语 ...
- 继承虚函数浅谈 c++ 类,继承类,有虚函数的类,虚拟继承的类的内存布局,使用vs2010打印布局结果。
本文笔者在青岛逛街的时候突然想到的...最近就有想写几篇关于继承虚函数的笔记,所以回家到之后就奋笔疾书的写出来发布了 应用sizeof函数求类巨细这个问题在很多面试,口试题中很轻易考,而涉及到类的时候 ...
- js中使用function定义类、实例化,函数的调用方法
function Test002(name, age){ name, age, this.printInfo = function(){ //定义的公有方法 console.log(name, age ...
- C++基础知识 基类指针、虚函数、多态性、纯虚函数、虚析构
一.基类指针.派生类指针 父类指针可以new一个子类对象 二.虚函数 有没有一个解决方法,使我们只定义一个对象指针,就可以调用父类,以及各个子类的同名函数? 有解决方案,这个对象指针必须是一个父类类型 ...
- (转)(C++)关于抽象基类和纯虚函数
★抽象类:一个类可以抽象出不同的对象来表达一个抽象的概念和通用的接口,这个类不能实例化(创造)对象. ★纯虚函数(pure virtual):在本类里不能有实现(描述功能),实现需要在子类中实现.例: ...
- C++函数中那些不可以被声明为虚函数的函数
转自C++函数中那些不可以被声明为虚函数的函数 常见的不不能声明为虚函数的有:普通函数(非成员函数):静态成员函数:内联成员函数:构造函数:友元函数. 1.为什么C++不支持普通函数为虚函数? 普通函 ...
- C++:抽象基类和纯虚函数的理解
转载地址:http://blog.csdn.net/acs713/article/details/7352440 抽象类是一种特殊的类,它是为了抽象和设计的目的为建立的,它处于继承层次结构的较上层. ...
- C++反汇编第三讲,反汇编中识别虚表指针,以及指向的虚函数地址
C++反汇编第三讲,反汇编中识别虚表指针,以及指向的虚函数地址 讲解之前,了解下什么是虚函数,什么是虚表指针,了解下语法,(也算复习了) 开发知识为了不码字了,找了一篇介绍比较好的,这里我扣过来了,当 ...
随机推荐
- SpringBoot获得application.properties中数据的几种方式
转:https://blog.csdn.net/qq_27298687/article/details/79033102 SpringBoot获得application.properties中数据的几 ...
- C# vb .net实现负片特效滤镜
在.net中,如何简单快捷地实现Photoshop滤镜组中的负片特效呢?答案是调用SharpImage!专业图像特效滤镜和合成类库.下面开始演示关键代码,您也可以在文末下载全部源码: 设置授权 第一步 ...
- 用HTML、CSS、JS制作圆形进度条(无动画效果)
逻辑 1.首先有一个圆:蓝色的纯净的圆,效果: 2.再来两个半圆,左边一个,右边一个将此蓝色的圆盖住,效果: 此时将右半圆旋转60°,就会漏出底圆,效果: 然后我们再用一个比底圆小的圆去覆盖这个大 ...
- IPv4如何转换为IPv6?
ipv6已经逐渐在应用,现在已经有很多的运营商支持ipv6,前天我们也发布了如何让电脑使用ipv6地址?有很多朋友在问?ipv6有什么作用,它的表示方式是什么,今天我们来一起来详细了解下ipv6相关计 ...
- 【开发笔记】- 发送邮件(通过JavaMail发送)
前段时间在工作中用到了邮件发送监控的报警信息,今天在这个记录一下JavaMail的邮件工具类. 下边为用到的JavaMail的jar包的pom依赖.这里用的是JavaMail的1.4.6的版本. &l ...
- Redis安装、主从配置及两种高可用集群搭建
Redis安装.主从配置及两种高可用集群搭建 一. 准备 Kali Linux虚拟机 三台:192.168.154.129.192.168.154.130.192.168.154 ...
- 自定义hybris生成订单的ID格式
在项目local.properties里做出如下定义: keygen.order.code.digits=8 keygen.order.code.start=00000000 keygen.order ...
- 介绍一种在ABAP内核态进行内表高效拷贝的方法,和对应的Java和JavaScript版本的伪实现
内表操作是ABAP开发人员几乎在每个ABAP程序里都会遇到的. 看一个例子:有两个行结构不一样的内表,每个内表的行结构有三列,除了name这一列名字一致外,其他两列的名称都不同,下图用红色和蓝色标注出 ...
- springboot+druid+mybatis
pom.xml <dependency> <groupId>com.microsoft.sqlserver</groupId> <artifactId> ...
- MySQL MGR--MGR部署
MGR部署 场景描述: 使用三台服务器搭建一个简单MGR集群,使用MySQL 5.7.24版本,服务器列表为: 192.168.1.147 192.168.1.148 192.168.1.149 1. ...