构造函数和析构函数的调用时机

1. 对于全局定义的对象,每当程序开始运行,在主函数 main 接受程序控制权之前,就调
用构造函数创建全局对象,整个程序结束时,自动调用全局对象的析构函数。
2. 对于局部定义的对象,每当程序流程到达该对象的定义处就调用构造函数,在程序离开
局部对象的作用域调用对象的析构函数。
3. 对于关键字 static 定义的静态对象,当程序流程到达该对象定义处调用构造函数,在整
个程序结束时调用析构函数。
4. 对于用 new 运算符创建的堆对象,每当创建该对象时调用构造函数,在使用 delete 删
除该对象时,调用析构函数

拷贝构造函数回顾

在看调用时机之前,先回顾以下拷贝构造函数的定义:

拷贝构造函数的形式是固定的:类名(const 类名 &)
1. 该函数是一个构造函数 —— 拷贝构造也是构造!
2. 该函数用一个已经存在的同类型的对象,来初始化新对象,即对对象本身进行复制
没有显式定义拷贝构造函数,这条复制语句依然可以通过,说明编译器自动提供了默认的
拷贝构造函数。其形式是:

Point(const Point & rhs)
: _ix(rhs._ix)
, _iy(rhs._iy)
{}

但是默认的拷贝构造函数只能实现浅拷贝,无法对复杂的数据结构进行深拷贝,示例如下:

Computer pc("Acer",4500);
Computer pc2 = pc;//调用拷贝构造函数class Computer{
public:void print(){cout << "name:" << _name << endl;cout << "price:" << _price << endl;}
private:int _price;char *_name;  
};

编译可以通过,运行则会报错。

如果是默认的拷贝构造函数,pc2会对pc的_brand进行浅拷贝,指向同一片内存;pc2被销
毁时,会调用析构函数,将这片堆空间进行回收;pc再销毁时,析构函数中又会试图回收
这片空间,出现double free问题

如果拷贝构造函数需要显式写出时(该类有指针成员申请堆空间),在自定义的拷贝构造函数中要换成深拷贝的方式,先申请空间,再复制内容

Computer::Computer(const Computer & rhs)
: _brand(new char[strlen(rhs._brand) + 1]())
, _price(rhs._price)
{
strcpy(_brand, rhs._brand);
}

拷贝构造函数的调用时机

1. 当使用一个已经存在的对象初始化另一个同类型的新对象时
2. 当函数参数(实参和形参的类型都是对象),形参与实参结合时(实参初始化形参)
—— 为了避免这次不必要的拷贝,可以使用引用作为参数

注意:类内拷贝构造函数必须对形参使用使用,否则会陷入对拷贝的递归调用导致栈溢出。

3. 当函数的返回值是对象,执行return语句时(编译器有优化)。
——为了避免这次多余的拷贝,可以使用引用作为返回值,但一定要确保返回值的生命
周期大于函数的生命周期

拷贝构造函数的形式探究

拷贝构造函数是否可以去掉引用符号?

Point(const Point  rhs)
—— 类名(const 类名) 形式,首先编译器不允许这样写,直接报错
如果拷贝函数的参数中去掉引用符号,进行拷贝时调用拷贝构造函数的过程中会发生“实参
和形参都是对象,用实参初始化形参”(拷贝构造第二种调用时机),会再一次调用拷贝构
造函数。形成递归调用,直到栈溢出,导致程序崩溃。

拷贝构造函数是否可以去掉const?

Point(Point & rhs)—— 类名(类名 &) 形式
编译器不会报错
加const的第一个用意:为了确保右操作数的数据成员不被改变
加const的第二个用意:为了能够复制临时对象的内容,因为非const引用不能绑定临时变量(右值)

先看一个简单的示例,看看什么是临时的变量或对象:

参考:https://zhuanlan.zhihu.com/p/165391845

#include <iostream>
using namespace std;void f(int &a){cout << "f(" << a  << ") is being called" << endl;
}void g(const int &a){cout << "g(" << a << ") is being called" << endl;
}int main(){int a = 3, b = 4;f(a + b);  //编译错误,把临时变量作为非const的引用参数,传递给int &a了g(a + b);  //OK,把临时变量作为const&传递是允许的
}

上面的两个调用之前,a+b的值会存在一个临时变量中,因为a+b是一个表达式,本质上属于一个没有名字的变量,编译器会自动生成一个临时变量储存a+b的值,当把这个临时变量传给f时,由于f的声明中,参数是int&,不是常量引用,所以产生以下编译错误:

error: invalid initialization of non-const reference of type 'int&' from a temporary of type 'int'

那么临时变量跟引用有什么关系?C++语法规定,const引用可以绑定右值,非const引用不能绑定右值。这里什么是左值和右值?

通俗的说,可以取地址的变量称为左值,反之则为右值。临时变量,匿名变量,临时对象,匿名对象他们在内存中并没有实际的内存分配,绝大多数情况下属于右值。对于没有实际存在于内存中的变量或对象,不允许直接对其进行引用,因为编译器认为引用的对象必须是内存中实体,面对这种情况,必须加const进行常量引用。

补充:【临时变量】不能作为【非const引用参数】,不是因为他是常量,而是因为c++编译器的一个关于语义的限制。如果一个参数是以非const引用传入,c++编译器就有理由认为程序员会在函数中修改这个值,并且这个被修改的引用在函数返回后要发挥作用。但如果你把一个临时变量当作非const引用参数传进来,由于临时变量的特殊性,程序员并不能操作临时变量,而且编译器认为临时变量不会常驻内存,随时可能被释放掉,所以,一般说来,修改一个临时变量是毫无意义的,据此,c++编译器加入了临时变量不能作为非const引用的这个语义限制,意在限制这个非常规用法的潜在错误。

回到之前的拷贝构造函数,由之前的疑问可以得出,拷贝构造函数必须让对象包含引用符号。

又因非const引用不能绑定临时变量,所以对于拷贝构造函数必须进行const引用。

对于下图中的示例,右边的Computer实际并未被完全实例化,就直接拷贝给了pc3对象,属于一个临时对象,这条语句执行完就被释放掉了。所以必须是const引用。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/news/920951.shtml
繁体地址,请注明出处:http://hk.pswp.cn/news/920951.shtml
英文地址,请注明出处:http://en.pswp.cn/news/920951.shtml

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

59.螺旋矩阵II

59.螺旋矩阵II 螺旋矩阵没有什么算法&#xff0c;就是一道单纯模拟转圈的一道题目&#xff0c;因为转圈的过程需要处理的边界条件很多&#xff0c;所以有难度 那只能从第二个节点开始处理&#xff1b;从第二个节点开始处理&#xff0c;把最后一个节点也处理了&#xff08;第二…

MS SQL(Microsoft SQL Server)面试常考的知识点

MS SQL是Microsoft SQL Server的简称&#xff0c;是由微软公司开发的一款关系型数据库管理系统&#xff08;RDBMS,Relational DataBase Management System&#xff09;。它支持在Windows和Linux上运行&#xff0c;广泛应用于企业级数据库市场&#xff0c;适用于大型企业网站和应…

百胜软件获邀出席第七届中国智慧零售大会,智能中台助力品牌零售数智变革

8月28日&#xff0c;由深圳市智慧零售协会主办的第七届中国智慧零售大会在深圳福田希尔顿酒店成功召开。本届大会以“聚势AI共启智慧零售新生态”为主题&#xff0c;汇聚了来自北京大学、腾讯云、百果园、舍得酒业、美宜佳等众多知名企业与机构的专家代表&#xff0c;共同探讨A…

QEMU使用Qemu-Guest-Agent传输文件、执行指令等

简介 之前介绍过qemu传输文件,使用的挂载 / samba方式 :Qemu和宿主机不使用外网进行文件传输。 这是一种方式,这里还有另一种方式:使用Qemu-Guest-Agent,后面简称qga。 官网介绍:https://www.qemu.org/docs/master/interop/qemu-ga.html 安装 这里有一篇参考文章,会…

HTML 核心标签全解析:从文本排版到媒体嵌入

在网页开发中&#xff0c;HTML&#xff08;超文本标记语言&#xff09;是构建页面结构的基石。掌握各类核心标签的用法&#xff0c;是实现页面内容有序呈现、提升用户体验的关键。本文将系统讲解 HTML 中最常用的几类标签 —— 段落标签、文本格式标签、列表标签、表格&#xf…

[后端快速搭建]基于 Django+DeepSeek API 快速搭建智能问答后端

在 AI 应用开发中&#xff0c;将大模型 API 与 Web 框架结合是常见需求。本文将详细记录如何使用 Django 搭建后端服务&#xff0c;并集成 DeepSeek API 实现智能问答功能&#xff0c;包含环境配置、路由设计、API 调用及异常处理的完整流程&#xff0c;适合需要快速搭建 AI 问…

R 语言 + 卒中 Meta 分析

R 语言 卒中 Meta 分析&#xff1a;4 类核心场景完整代码&#xff08;含药物对比 / 剂量风险&#xff09; 卒中&#xff08;缺血性 / 出血性&#xff09;的临床决策高度依赖循证证据&#xff0c;而 Meta 分析是整合多中心研究结果的核心工具。本文以卒中临床研究为核心&#x…

Goframe 框架下HTTP反向代理并支持MCP所需的SSE协议的实现

一、需求背景 Go 语言开发 MCP 服务&#xff0c;并在 Goframe 框架下实现 Http 反向代理&#xff0c;代理该 MCP 服务。 二、效果演示 三、Goframe框架简介 GoFrame 是一款模块化、低耦合设计、高性能的Go 语言开发框架。包含了常用的基础组件和开发工具&#xff0c;既可以作…

Git将多笔patch合并成一笔

一、方法1、在你的代码中把这多笔patch都打上2、git reset到origin那一笔(默认模式&#xff0c;不带soft或者hard)3、再add和commit&#xff0c;push二、种模式对比模式命令示例影响范围适用场景--softgit reset --soft HEAD~1仅移动 HEAD&#xff0c;保留修改在暂存区修改提交…

【SpringBoot】Dubbo、Zookeeper

文章目录前提知识概要分布式系统单体架构垂直应用架构分布式架构流式架构RPCDubbo概念Dubbo环境搭建Zookeeper测试 ZookeeperWindow环境下使用Dubbo-admin版本匹配不对服务注册实战内容总结导入相关依赖选择 Zookeeper 版本配置并启用 Zookeeper创建服务接口和实现(DubboServic…

【不说废话】pytorch张量相对于numpy数组的优势

核心关系 我们首先需要了解&#xff1a;PyTorch 张量在设计上深受 NumPy 数组的影响&#xff0c;它们共享许多相似的 API 和概念。实际上&#xff0c;PyTorch 张量可以看作是支持 GPU 加速和自动求导功能的 NumPy 数组。PyTorch 张量的主要优势 1. GPU 加速支持&#xff08;最重…

拼团小程序源码分享拼团余额提现小程序定制教程开发源码二开

功能详细说明&#xff08;一&#xff09;首页功能进入首页&#xff0c;可看到以下核心功能&#xff1a;1、优惠券&#xff0c;钱包&#xff0c;签到&#xff0c;拼团&#xff0c;分销等各种功能入口2、推荐的商品和活动3、下方功能栏的各种功能&#xff08;二&#xff09;客服功…

pikachu之XSS

XSS&#xff08;跨站脚本&#xff09;概述Cross-Site Scripting 简称为“CSS”&#xff0c;为避免与前端叠成样式表的缩写"CSS"冲突&#xff0c;故又称XSS。一般XSS可以分为如下几种常见类型&#xff1a;1.反射性XSS;2.存储型XSS;3.DOM型XSS;XSS漏洞一直被评估为web漏…

【Element Plus `el-select` 下拉菜单响应式定位问题深度解析】

Element Plus el-select 下拉菜单响应式定位问题深度解析 本文档旨在深入剖析一个在响应式布局中常见的 UI 问题&#xff1a;如何确保一个靠近屏幕边缘的 el-select 组件的下拉菜单&#xff0c;在任何屏幕尺寸下都能以预期的、优雅的方式显示。 1. 需求背景 在一个大屏数据展示…

Qt 项目文件(.pro)中添加 UI 文件相关命令

在 Qt 的 .pro 项目文件中&#xff0c;处理 UI 文件&#xff08;.ui 文件&#xff09;通常需要以下配置&#xff1a; 基本 UI 文件配置 自动包含 UI 文件&#xff1a; qmake FORMS yourfile.ui \anotherfile.ui Qt 构建系统会自动使用 uic&#xff08;用户界面编译器&#xff…

展会回顾 | 聚焦医疗前沿 , 礼达先导在广州医博会展示类器官自动化培养技术

8月22-24日&#xff0c;广州医博会在广交会展馆B区圆满落幕。此次盛会汇聚了来自全球医疗健康领域的顶尖专家学者、企业代表与合作伙伴。展会内容涵盖基础研发、临床应用、前沿技术、产业转化、医疗服务及金融支持&#xff0c;全景呈现医疗健康产业的创新生态&#xff0c;成为连…

华为eNSP防火墙综合网络结构训练.docx

1.IP及VLAN规划情况 设备 接口 IP vlan 备注 AR1 g0/0/0 1.1.1.2/28 PPPOE g0/0/1 3.3.3.1/30 g0/0/2 114.114.114.254/24 AR2 g0/0/0 2.2.2.2/28 DHCP g0/0/1 3.3.3.2/30 g0/0/2 100.100.100.254/24 FW1 g1/0/0 10.0.0.1/30 tr…

从 Oracle 到 TiDB,通过ETL工具,高效实现数据拉通

在当前企业数字化转型的浪潮中&#xff0c;打破数据孤岛、实现异构数据库间的数据高效流转已成为提升业务敏捷性与决策效率的关键。许多企业在要将 Oracle 数据库中的海量数据准确地同步至TiDB 分布式数据库时遇到了挑战。这一过程不仅要求数据的绝对一致性&#xff0c;还对同步…

Effective c++ 35条款详解

您问到了最关键的一点&#xff01;这正是策略模式的精妙之处——它通过组合&#xff08;composition&#xff09;而非继承&#xff08;inheritance&#xff09;来实现多态效果。让我详细解释这是如何工作的&#xff0c;以及它与传统继承多态的区别。&#x1f504; 策略模式如何…

51c自动驾驶~合集19

自己的原文哦~ https://blog.51cto.com/whaosoft/11793894 #DRAMA 首个基于Mamba的端到端运动规划器 运动规划是一项具有挑战性的任务&#xff0c;在高度动态和复杂的环境中生成安全可行的轨迹&#xff0c;形成自动驾驶汽车的核心能力。在本文中&#xff0c;我…