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++反汇编第三讲,反汇编中识别虚表指针,以及指向的虚函数地址 讲解之前,了解下什么是虚函数,什么是虚表指针,了解下语法,(也算复习了) 开发知识为了不码字了,找了一篇介绍比较好的,这里我扣过来了,当 ...
随机推荐
- hystrix中request cache请求缓存
有一个概念,叫做reqeust context,请求上下文,一般来说,在一个web应用中, 我们会在一个filter里面,对每一个请求都施加一个请求上下文,就是说,tomcat容器内,每一次请求,就是 ...
- mysql中length与char_length字符长度函数使用方法
在mysql中length是计算字段的长度一个汉字是算三个字符,一个数字或字母算一个字符了,与char_length是有一点区别,本文章重点介绍第一个函数. mysql里面的length函数是一个用来 ...
- oracle 数据库触发器,插入更新时间戳
1.首先建立一个测试表 CREATE TABLE TestTragger( UserId int Primary Key, Name VARCHAR() Not Null, CreateTime Ti ...
- Java 之 Session
Session 一.概述 Session技术:服务器端会话技术,在一次会话的多次请求间共享数据,将数据保存在服务器端的对象(HttpSession)中. 二.使用步骤 1.获取 HttpSession ...
- Python运算符大全
一. Python的算术运算 Python的算术运算符与C语言类似,略有不同.包括加(+).减(-).乘(*).除(/).取余(%).按位或(|).按位与(&).按位求补(~).左移位(< ...
- Java -- springboot 配置 freemarker
1.添加依赖 org.springframework.boot spring-boot-starter-freemarker 2.配置application.properties spring.fre ...
- Spark之开窗函数
一.简介 开窗函数row_number()是按照某个字段分组,然后取另外一个字段排序的前几个值的函数,相当于分组topN.如果SQL语句里面使用了开窗函数,那么这个SQL语句必须使用HiveConte ...
- VSCode 控制台面板输出乱码 字符编码问题 PHP --已解决
首先上一张效果图,看看是不是你想要的效果. 第一步: 按F1,输入settings.json,添加 "code-runner.runInTerminal": true, 第二步:将 ...
- 常用docker管理UI
1. HumpBacks 特性 Web UI Supporting, Easy to use. Container Grouping and Isolation. Container Upgrades ...
- influxDB应用及TICK stack
InfluxData平台用于处理度量和事件的时间序列平台,常被称为TICK stack,包含4个组件:Telegraf,influxDB,Chronograf和Kapacitor,分别负责时间序列数据 ...