C++语法|如何写出高效的C++代码(一)|对象使用过程中背后调用了哪些方法(构造和析构过程)?

news2025/1/12 18:55:45

文章目录

  • 再探拷贝构造函数和重载复制运算符
    • 实例化新对象和赋值操作
    • 强转为类类型
    • 指针和引用时临时对象的构造和析构过程
  • 考考你
    • 问题
    • 答案

再探拷贝构造函数和重载复制运算符

实例化新对象和赋值操作

首先我们写一个类,实现它的拷贝构造并重载赋值运算符。

class Test {
private:
	int ma;
public:
	Test(int a = 10): ma(a) {
		cout << "Test()构造函数" << endl;
	}
	~Test() {
		cout << "~Test析构函数" << endl;
	}
	Test(const Test& t) {
		cout << "Test const Test& t拷贝构造函数" << endl;
	}
	Test& operator=(const Test& t) {
		ma = t.ma;
		cout << "operator = 重载赋值运算符" << endl;
		return *this;
	}
};

然后我们构造类的对象,主要探究什么时候调用重载赋值运算符、什么时候调用拷贝构造

int main () {
	Test t1;
	Test t2(t1);
	Test t3 = t2;
	Test t4 = Test(20);
	cout << "-------------" << endl;
	return 0;
}

结果如下:

为什么没有调用我们的t3和t4没有调用重载赋值运算符呢?

首先t3调用的是拷贝构造函数,说明本质上这是一条构造语句,如果写成

Test t3;
t3 = t2; // 这里调用了重载的赋值运算符

再一个t4是直接调用构造函数,那是因为Test(20)显示生成临时对象,它的生命周期为所在语句,所以它被编译器优化了,实际上调用的是Test t4(20);,如果写成:

//t4.operator=(t2)
t4 = t2; //赋值,没有生成新对象
// t4.operator=(const Test &t)
t4 = Test(20); //这个临时对象会构造一个新对象,然后赋值给t4

此处的Test(20)会就会调用构造函数了,并且t4=会调用重载赋值构造函数,也就是说,只要我们不是在进行初始化对象,而是在赋值某个对象的话,就会调用重载赋值运算符。

强转为类类型

接着上面的代码

t4 = (Test)30; // int->Test

这样能转吗?其实是可以的,编译器会寻找Test类是否有一个合适的构造函数。显然我们这里是有的,因为我们的构造函数默认输入一个整形变量,所以编译器会为我们生成一个临时对象。甚至我们可以写成:这样的话我们是隐式生成临时对象。

t4 = 30;
//t4 = "aaa"; 报错,因为我们没有实现带char*类型的构造函数

指针和引用时临时对象的构造和析构过程

我们想考察一下指针和引用来获取临时对象:

Test *p = &Test(40);
//p指向的是一个已经析构的临时对象,该指针变为野指针
const Test &ref = Test(40);
//Test &ref = Test(30); 报错,必须是常引用

这里的指针甚至不能编译,这是由于较新的编译器代码检查机制更加严格,放以前肯定就编译通过了。并且该指针一定会成为野指针,因为出语句之后临时对象就会析构。并且较新的编译器const Test &ref = Test(40)也会报错,报错语句为:

error: taking the address of a temporary object of type 'Test' [-Waddress-of-temporary]

结论:在较新版本的编译器中,无论是用常引用还是指针,都不能指向一个临时对象

考考你

问题

对于以下类:

class Test {
public:
	// Test() Test(a) Test(b)
    Test(int a = 5, int b = 5) : ma(a), mb(b) {
        cout << "Test()构造函数" << endl;
    }
    ~Test() {
        cout << "~Test()析构函数" << endl;
    }
    Test(const Test& src) : ma(src.ma), mb(src.mb) {
        cout << "Test(const Test&)拷贝构造函数" << endl;
    }

    Test& operator=(const Test& src) {
        ma = src.ma;
        mb = src.mb;
        cout << "operator=(const Test&)重载赋值运算符" << endl;
        return *this;
    }
private:
    int ma;
    int mb;
};

我们这样实例化这个类,请问每条语句都调用了类的哪些成员函数呢?

Test t1(10, 10);//1.Test(int, int)
int main() {
	Test t2(20, 20);//3.Test(int, int)
	Test t3 = t2; //4.Test(const Test&)
	/*
	静态变量和全局变量程序运行的时候内存就已经存在了,
	因为数据段内存是事先就分配好的
	但是静态局部变量只在第一次运行到它才会初始化,所以并不会构造先t4
	*/
	//static Test t4(30,30);
	static Test t4 = Test(30, 30);//5.Test(int, int)
	t2 = Test(40, 40); //6.Test(int, int) operator= ~Test()
	//(50, 50) = 50 逗号表达式
	t2 = (Test)(50, 50);//7.(Test)50; Test(int, int) operator= ~Test()
	t2 = 60;	// Test(int) 8.Test(int, int) operator= ~Test()
	Test *p1 = new Test(70, 70); //9. Test(int, int)
	Test *p2 = new Test[2]; // 10. Test(int, int) Test(int, int)
	//较新的编译器无法通过编译
	Test *p3 = &Test(80, 80);  //11.Test(int, int) ~Test()
	const Test &p4 = Test(90, 90); //12.Test(int, int)
	delete p1; //13.~Test() 然后free内存
	delete[]p2; //14.~Test() ~Test() 然后free内存
}
Test t5(100, 100); //2. Test(int, int)

运行以后,这个类的构造、析构、拷贝构造的调用过程已经写在注释中了,并且最后的析构顺序为p1->p2->p4->t3->t2->t4->t5->t1 一共应该是9连析构

答案

你答对了吗?(这里的输出结果是注释Test *p3 = &Test(80, 80);后的结果)

在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

算法学习006-瓷砖总数 广度优先算法BFS 中小学算法思维学习 信奥算法解析 c++实现

目录 C瓷砖总数 一、题目要求 1、编程实现 2、输入输出 二、算法分析 三、程序编写 四、程序说明 五、运行结果 六、考点分析 七、推荐资料 C瓷砖总数 一、题目要求 1、编程实现 在一个长方形房间&#xff0c;铺着不同颜色的的瓷砖&#xff0c;有红色和黑色&#…

流畅的python-学习笔记_序列修改+散列+切片

vector第一版 reprlib.repr用于选取有限长度较长变量 vector第二版切片 注意切片还有indices属性&#xff0c;它可以入参一个序列长度&#xff0c;根据此序列长度&#xff0c;转化不规矩的start stop stride&#xff0c; vector第三版动态存取属性 obj.attra时&#xff0c;先…

WordPress MasterStudy LMS插件 SQL注入漏洞复现(CVE-2024-1512)

0x01 产品简介 WordPress和WordPress plugin都是WordPress基金会的产品。WordPress是一套使用PHP语言开发的博客平台。该平台支持在PHP和MySQL的服务器上架设个人博客网站。WordPress plugin是一个应用插件。 0x02 漏洞概述 WordPress Plugin MasterStudy LMS 3.2.5 版本及之…

长难句打卡5.6

For H&M to offer a $5.95 knit miniskirt in all its 2,300-plus stores around the world, it must rely on low-wage overseas labor, order in volumes that strain natural resources, and use massive amounts of harmful chemicals. 翻译:H&M若要在其全球总共2…

JavaScript异步编程——05-回调函数

我们在前面的文章《JavaScript 基础&#xff1a;异步编程/单线程和异步》中讲过&#xff0c;Javascript 是⼀⻔单线程语⾔。早期我们解决异步场景时&#xff0c;⼤部分情况都是通过回调函数来进⾏。 &#xff08;如果你还不了解单线程和异步的概念&#xff0c;可以先去回顾上一…

多模态中的“单流模型”和“双流模型”

多模态预训练模型按照模型结构可以分为单流和双流两种结构。 单流是指图片和文本在embedding之后就融合在一起进入后续的transformer层。【先将信息fusion&#xff0c;然后再用一个model处理】双流是指文本和图片单独享有自己的transformer层&#xff0c;只在最后做轻量的融合…

添砖Java之路其二——基本数据类型,scanner,字符拼接。

目录 基本数据类型&#xff1a; ​编辑 Scanner: 字符拼接&#xff1a; 课后小题&#xff1a; 基本数据类型&#xff1a; 如图可见&#xff1a;Java里面有八种基本数据类型。 注意&#xff1a;在其中我们需要注意的是int默认整型数据&#xff0c;double是默认浮点型数据。因…

IP协议全解析:网络层通信的基石

⭐小白苦学IT的博客主页⭐ ⭐初学者必看&#xff1a;Linux操作系统入门⭐ ⭐代码仓库&#xff1a;Linux代码仓库⭐ ❤关注我一起讨论和学习Linux系统❤ 前言 在数字化时代的浪潮中&#xff0c;网络通信无处不在&#xff0c;它连接着世界的每一个角落&#xff0c;承载着信息的高…

OpenNJet产品体验-手把手在Ubuntu20.04系统从零部署到应用OpenNJet

目录 一、引言 二、OpenNJet产品安装 2.1下载OpenNJet安装包 2.2安装OpenNJet V2.0.1 ​2.3快速启动并测试OpenNJet 三、OpenNJet产品应用体验 3.1配置OpenNJet 3.2 部署 Web 应用程序 3.3启动 NJet 3.4访问 Web 应用程序 四、总结 一、引言 OpenNJet应用引擎是高性…

文件加密软件排行榜前四名|好用的四款文件加密软件分享

在数据泄露事件频发的今天&#xff0c;文件加密软件成为了保护个人隐私与企业信息安全的必备工具。 选择一款高效、可靠且易用的加密软件至关重要。 本文精选了当前市场上备受好评的十款文件加密软件&#xff0c;旨在为您在数据保护之旅中提供方向。 1.域智盾 域智盾软件是一…

书单 | 6本AI领域名家名作,大模型时代,趁风而起!

–文末赠书– 大模型时代&#xff0c;想抓住风口吗&#xff1f; 本期书单就来分享6本AI领域名家名作&#xff0c;给大家把大模型时代那些事儿讲清楚&#xff01; 放心&#xff0c;入门的同学也可以从最基础的学起~~ 快来看看有哪些书吧…… 01 ▊《多模态大模型&#xff1…

【JAVA基础之时间API】自定义时间格式

&#x1f525;作者主页&#xff1a;小林同学的学习笔录 &#x1f525;mysql专栏&#xff1a;小林同学的专栏 目录 1.Date类 1.1 概述 1.2 构造方法 1.3 常用方法 2.SimpleDateFormat类 2.1 概述 2.2 构造方法 2.3 格式规则 2.4 常用方法 3.Calendar类 3.1 概述…

SOLIDWORKS Electrical电气元件智能开孔

实际的电气元器件安装中&#xff0c;一些元器件需要穿过孔洞安装&#xff0c;例如按钮、指示灯会在配电柜的控制面板上&#xff0c;需要穿过控制面板安装。这部分内容放在软件建模、装配时&#xff0c;往往比较复杂因为考虑孔的大小符合元器件规格、孔跟随元器件移动、同一元器…

Docker入门篇来啦~

文章目录 1虚拟化技术1.1 硬件级虚拟化1.2 操作系统级虚拟化 2 Docker是什么2.1 Docker介绍2.2 容器和虚拟机的区别2.3 为什么使用Docker 3 Docker运行环境部署3.1 Docker安装3.2 Docker服务启动 4 Docker核心组件4.1 镜像4.1.1 镜像的基本概念4.1.2 镜像的组成结构4.1.3 镜像的…

牛客 二叉树 NB1 牛群的最大高度

原题链接 就不采用, 递归的方式来做了, 自己弄个栈来做 用栈来保存路径, curr 表示当前的节点, pre 保留往回走时的上一步 如果是 用递归来做 它的栈链路是这样的, 可以做下参考 黄色表示返回 用栈模拟的话, 不可能模拟得一摸一样, 递归的话一个栈会经过3次, 第三次后就不…

去除图片水印软件-inpaint

一、普通使用教程 亲眼看看使用 Inpaint 从照片中删除不需要的元素是多么容易&#xff1a; 1.1加载图片 1.2 选择要纠正的问题区域 1.3 告别不需要的对象并保存 二、功能 1 修复旧照片 老并不总是意味着坏。我们拥有的一些旧照片对我们来说仍然很重要&#xff0c;因为它们仍…

OpenCV 入门(二)—— 车牌定位

OpenCV 入门系列&#xff1a; OpenCV 入门&#xff08;一&#xff09;—— OpenCV 基础 OpenCV 入门&#xff08;二&#xff09;—— 车牌定位 OpenCV 入门&#xff08;三&#xff09;—— 车牌筛选 OpenCV 入门&#xff08;四&#xff09;—— 车牌号识别 OpenCV 入门&#xf…

[附源码]秦时明月6.2魔改版_搭建架设教程_附GM工具_安卓苹果

本教程仅限学习使用&#xff0c;禁止商用&#xff0c;一切后果与本人无关&#xff0c;此声明具有法律效应&#xff01;&#xff01;&#xff01;&#xff01; 教程是本人亲自搭建成功的&#xff0c;绝对是完整可运行的&#xff0c;踩过的坑都给你们填上了 一. 演示视频 秦时明…

[嵌入式AI从0开始到入土]17_Ascend C算子开发

[嵌入式AI从0开始到入土]嵌入式AI系列教程 注&#xff1a;等我摸完鱼再把链接补上 可以关注我的B站号工具人呵呵的个人空间&#xff0c;后期会考虑出视频教程&#xff0c;务必催更&#xff0c;以防我变身鸽王。 第1期 昇腾Altas 200 DK上手 第2期 下载昇腾案例并运行 第3期 官…

libcity/model/trajectory_loc_prediction/DeepMove.py

1 DeepMove 1.1 构造函数 1.2 初始化权重 1.3 forward 1.4 predict def predict(self, batch):score self.forward(batch)if self.evaluate_method sample:# build pos_neg_inedxpos_neg_index torch.cat((batch[target].unsqueeze(1), batch[neg_loc]), dim1)score tor…