c++ 虚函数与析构函数
创始人
2025-05-31 03:06:26
0

   构造函数是不能为虚函数的,但析构函数能够且常常必须是虚的。

   构造函数,先调用基类的构造函数,其次调用更晚的派生类的构造函数。

   析构函数和构造函数的顺序相反。

#include
using namespace std;
class Base1
{
public:~Base1(){cout<<"~Base1()\n";}
};class Derived1:public Base1
{
public:~Derived1(){cout<<"~ Derived1"<

~Base1()
~ Derived2
~Base2()

delete bp只调用基类的析构函数 。

delete bp2 调用了派生类的析构函数。

析构函数是虚函数,可以避免内存泄漏的问题。

纯虚析构函数

  纯虚构函数必须是合法的,且在实用时,有一个限制,必须为纯虚函数提供一个函数体。

为什么?析构函数总要按顺序进行调用,如果没有实体,调用什么呢?

纯虚构函数和虚构函数的区别是什么:

     纯虚构函数使基类是抽象类,抽象类,不可以创建对象。

从某个含有虚析构函数的类中,继承一个类,不向其它纯虚函数,我们不要求在派生类中提供纯虚函数的定义。因为编译器会自动生成虚构函数。

#include
using namespace std;
class Base
{
public:virtual ~Base() = 0;
};
class Derive:public Base
{}
int main()
{}

不会出现编译错误。

当我们类中,仅含有一个纯虚函数:

   析构函数的纯虚性,唯一效果可以阻止基类的实例化。

   如果有其他纯虚构函数将会执行这一操作,所以当虚析构函数是十分必要的,它是不是存虚的就没有那么重要。

 

#include
using namespace std;
class Base
{
public:virtual ~Base() = 0;
};
Base::~Base()
{cout<<"~ Base"<

  ~ Base

 可以看到,基类的纯虚构函数会被调用。

作为一个准则,任何时候,我们的类中,都要有一个虚函数,我们应当增加一个虚析构函数,即使我们什么都不做。

析构函数的虚机制

using namespace std;
class Base
{
public:virtual ~Base();virtual void  f(){cout<<"Base f function\n";}
};
Base::~Base()
{cout<<"~ Base"<

~ Derive
~ Base
Base f functio

 在虚析构函数中调用函数,无论被调用的函数是否是虚析构函数,调用的都是本地的函数。

向下类型转换

#include
using namespace std;
class Base
{
public:virtual ~Base(){}
};
class Derive:public Base
{
public:~Derive(){};
};
class Derive2:public Base
{
public:~Derive2(){};
};
int main()
{Base *p = new Derive;Derive *pD = dynamic_cast(p);Derive2 *pD2 = dynamic_cast(p);cout<<"pD = "<<(long)pD<

pD = 27020320
pD2 = 0

 

#include
using namespace std;
class Base
{
public:virtual ~Base(){}
};
class Derive:public Base
{
public:~Derive(){};
};
class Derive2:public Base
{
public:~Derive2(){};
};
int main()
{Base *p = new Derive;Derive *pD = dynamic_cast(p);Derive2 *pD2 = dynamic_cast(p);cout<<"pD = "<<(long)pD< p;}//使用static_cast 可以先判断typeid是否一致}

相关内容

热门资讯

python基础语法【模块 包... 模块 包 异常捕获 1.模块 python一个py文件就是一个模块 1.1 使用方法 1)前提&#x...
在recyclerview中使... 问题描述 最近在使用RecycerView的瀑布流布局,我想直接用ViewBindin...
java中Long型数据大小比... 起因 今天在做项目的时候,想构建一个树形结构,从数据库中查询出了所有数据...
智能控制 | AIRIOT智慧... 许多行业客户在智慧楼宇的建设中主要面临运营管理低效,楼宇内部各个系统相互独立ÿ...
Redis 数据结构 这里写目录标题Redis 数据结构一、String类型String数据类型的使用场景key 的设置约...
基于 MM32SPIN0280... M32SPIN0280 是灵动微电机新推出的针对电机控制市场的专用 MCU,该系列 M...
C++学习(指针、引用、结构体... 1编译软件Visual Studio2基本语法2.1指针2.1.1指针的使用//定义一个指针int ...
【UML】项目开发流程 以下模型是一个项目从启动到最终部署,逐步细化(精化)、实现...
docker-java应用部署 目录          1端口映射 2.Mysql部署 3.Tomcat部署 4.Nginx部署 5...
CentOS操作系统libc.... 使用xshell登陆Linux后查看jdk版本提示 /lib64/libc.so.6: versio...
Linux串口实现树莓派与电脑... 目录 一  串口说明 二  USB—TTL模块 ● usb-ttl模块接口  三  串口通信常用的A...
BeanPostProcess... 文章目录一、BeanPostProcessor的作用1. 源码2. 使用案例二、Spring生命周期...
2023.3.22 文章目录@13:static关键字**一:static修饰变量&...
模糊PID控制双容水箱液位控制... 资源:双容水箱液位模糊PID控制MATLAB仿真-电子商务文档类资源-CSDN文库模糊...
基于springboot家政服... 大家好✌!我是CZ淡陌。一名专注以理论为基础实战为主的技术博主,将再这里...
提升代码质量,使用插件对 ja... 目录前言一、使用maven-checkstyle-plugin插件1. maven-checksty...
VSCode配置git bas... 打开左下角齿轮图标      打开Settings 搜索框输入 terminal.integrat...
Winform控件开发(21)... 一、属性 1、Name 用于获取控件对象 2、Anchor 锚定控件对于父控件的位置 3、BackC...
【kubernetes云原生】... 目录 一、标签选择器来源 二、什么是标签选择器 2.1 标签选择器概述 2.2 标签选择器概述属性 ...
重构条件-Replace Ne... 重构条件-Replace Nested Conditional with Guard Clauses...