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++反汇编第三讲,反汇编中识别虚表指针,以及指向的虚函数地址 讲解之前,了解下什么是虚函数,什么是虚表指针,了解下语法,(也算复习了) 开发知识为了不码字了,找了一篇介绍比较好的,这里我扣过来了,当 ...
随机推荐
- 查询系统table条数
), RowCnt INT) EXEC sp_MSforeachtable 'INSERT INTO temp SELECT ''?'',COUNT(*) FROM ?' SELECT TableNa ...
- SQL注入获取Sa账号密码
漏洞位置:http://168.1.1.81/Information/Search?Keyword=1111 漏洞利用: MSSQL 2000 http://168.1.1.81/Informatio ...
- hystrix,request collapser,请求合并
多个商品,需要发送多次网络请求,调用多次接口,才能拿到结果 可以使用HystrixCollapser将多个HystrixCommand合并到一起,多个command放在一个command里面去执行,发 ...
- sqoop与hbase导入导出数据
环境:sqoop1.4.6+hadoop2.6+hbase1.1+mysql5.7 说明: 1.文中的导入导出的表结构借鉴了网上的某篇博客 2.mysql导入hbase可以直接通过sqoop进行 3. ...
- 【转载】 C#中decimal.TryParse方法和decimal.Parse方法的异同之处
在C#编程过程中,decimal.TryParse方法和decimal.Parse方法都可以将字符串string转换为decimal类型,但两者还是有区别,最重要的区别在于decimal.TryPar ...
- js的一些较为常见的语句算法题
下面各题解法可能存在一些时间和空间复杂度问题,有些没有做到最优化,还请谅解!!! 1.用for循环实现10的阶乘. //使用for循环方法解答 var num = 10 var sum = 1; va ...
- vue从零开始(二)指令
一.v-text和v-html <span v-text="msg"></span> <div v-html="html"> ...
- 冠捷显示成功的信息化建设(MES应用案例)
企业介绍 冠捷科技集团是驰誉全球的大型高科技跨国企业,产品包括彩色显示器( CRT monitor ).液晶显示器( LCD monitor ).液晶电视( LCD-TV )与等离子电视( PDP ) ...
- centos7 上Docker安装与启动
1. docker centos 文档地址 https://docs.docker.com/install/linux/docker-ce/centos/ 2. 安装环境说明: docker社区版 ...
- [LeetCode] 647. 回文子串 ☆☆☆(最长子串、动态规划、中心扩展算法)
描述 给定一个字符串,你的任务是计算这个字符串中有多少个回文子串. 具有不同开始位置或结束位置的子串,即使是由相同的字符组成,也会被计为是不同的子串. 示例 1: 输入: "abc" ...