C++ 构造函数、析构函数调用虚函数

news/2024/12/27 10:03:34/

C++虚函数是通过虚表实现的,虚函数的地址记录在需表中,只对象完成构造完成后,虚函数的地址才最终确定。

构造函数中调用虚函数

基类先于派生类构造,所以构造时没法调用到派生类的虚函数,也就是说只能调用到自己,也就是虚函数失去多态功能。

析构函数调用虚函数

派生类先于基类析构,所以析构时基类没法调用到派生类的虚函数,同样只能调用到自己,虚函数也失去多态功能。

代码

#include <iostream>class Base
{
public:Base(){std::cout << "Base Construct.  ";this->fun2("Base::Base");}virtual ~Base(){std::cout << "Base Destruct.  ";this->fun2("Base::~Base");}virtual void fun(){std::cout << "Base::fun" << std::endl;}virtual void fun2(const char* caller){std::cout << "Base::fun2, caller: " << caller << std::endl;}
};class Derive : public Base
{
public:Derive(){std::cout << "Derive Construct.  ";this->fun2("Derive::Derive");}~Derive() override{std::cout << "Derive Destruct.  ";this->fun2("Derive::~Derive");}void fun2(const char* caller) override{std::cout << "Derive::fun2: caller: " << caller << std::endl;}void fun() override{std::cout << "Derive::fun" << std::endl;}
};int main()
{Base *p = new Derive;delete p;return 0;
}

运行结果:

Base Construct.  Base::fun2, caller: Base::Base
Derive Construct.  Derive::fun2: caller: Derive::Derive
Derive Destruct.  Derive::fun2: caller: Derive::~Derive
Base Destruct.  Base::fun2, caller: Base::~Base

在构造函数函数或者析构函数中调用虚函数,通常IDE会有警告,为了消除警告可以通过域名符号调用虚函数,此时相当于直接指定函数地址,不需要通过虚表所以不会有警告

class Base
{
public:Base(){std::cout << "Base Construct.  ";Base::fun2("Base::Base"); // 虚函数}virtual ~Base(){std::cout << "Base Destruct.  ";Base::fun2("Base::~Base"); // 虚函数}virtual void fun(){std::cout << "Base::fun" << std::endl;}virtual void fun2(const char* caller){std::cout << "Base::fun2, caller: " << caller << std::endl;}
};

类函数指针

当类函数指针指向一个虚函数时,同样会触发多态,并不会直接调用函数指针对应的函数

#include <iostream>class Base
{
public:virtual void fun(){std::cout << "Base::fun" << std::endl;}};class Derive : public Base
{
public:void fun() override{std::cout << "Derive::fun" << std::endl;}
};int main()
{Base *p = new Derive;p->fun();p->Base::fun();auto pBFun = &Base::fun;auto pDFun = &Derive::fun;(p->*pBFun)();((Derive*)p->*pDFun)();return 0;
}

结果

Derive::fun
Base::fun
Derive::fun
Derive::fun


http://www.ppmy.cn/news/1073788.html

相关文章

universal robot 机械臂 官方基本教程

https://academy.universal-robots.cn/modules/e-Series-core-track/Chinese/module3/story_html5.html?courseId2166&languageChinese 教程1 控制箱内部 包含&#xff1a; 主机板&#xff0c;SD卡&#xff0c;和安全控制板 安全控制板负责所有控制信息&#xff0c;包括…

GiraffeDet助力yolov8暴涨分---有可执行源码

Yolov8魔改–加入GiraffeDet模型提高小目标效果 VX搜索晓理紫关注并回复有yolov8-GiraffeDet获取代码 [晓理紫] 1 GiraffeDet模型 GiraffeDet是一种新颖的粗颈范例&#xff0c;一种类似长颈鹿的网络&#xff0c;用于高效的目标检测。 GiraffeDet 使用极其轻量的主干和非常深且…

C语言二——依次将10个数输入,要求将其中最大的数输出

这是一个简单的C语言程序&#xff0c;它会接受用户输入的10个整数&#xff0c;然后找出最大值并输出。 程序的执行步骤如下&#xff1a; 声明一个数组 n&#xff0c;用于存储用户输入的10个整数&#xff0c;声明一个变量 i 和 t。提示用户输入10个数。使用 for 循环&#xff…

你觉得 Android 还有必要继续吗?

前言 这些年&#xff0c;总是听到有人说Android 开发岗位要凉了&#xff0c;不好做了。坦白说&#xff0c;市场倾向理性&#xff0c;竞争变强是很正常的事。但你发现总有些人&#xff0c;他们拿的 Offer 薪资是更高的&#xff0c;能达到年薪五六十万&#xff0c;甚至年薪百万。…

SpringBoot常用的简化开发注解

一、引言 在Spring Boot框架中&#xff0c;有许多常用的注解可用于开发项目。下面是其中一些常见的注解及其功能和属性的说明&#xff1a; 1、RestController RestController 是 Spring Framework 中的一个注解&#xff0c;用于标识一个类是 RESTful 服务的控制器。它结合了…

接口幂等性设计的最佳实现

一、什么是幂等 二、为什么需要幂等 三、接口超时了&#xff0c;到底如何处理&#xff1f; 四、如何设计幂等 全局的唯一性ID 幂等设计的基本流程 五、实现幂等的8种方案 selectinsert主键/唯一索引冲突 直接insert 主键/唯一索引冲突 状态机幂等 抽取防重表 token令牌 悲观锁…

Linux 安装mysql(ARM架构)

添加mysql用户组和mysql用户 安装依赖libaio yum install -y libaio* 下载Mysql wget https://obs.cn-north-4.myhuaweicloud.com/obs-mirror-ftp4/database/mysql-5.7.27-aarch64.tar.gz安装mysql 解压Mysql tar xvf mysql-5.7.27-aarch64.tar.gz -C /usr/local/ 重命名 …

SCI论文必备Latex使用技巧【随时更新】

\pi —— π \xi —— ξ \eta —— η \mu —— μ \rho —— ρ \phi —— ϕ \psi —— ψ \zeta —— ζ \beta —— β \delta —— δ \alpha —— α \theta —— θ \sigma —— σ \partial —— ∂ \gamma —— γ \epsilon —— ϵ \lambda —— λ \omega —— ω …