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

文章目录

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

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

实例化新对象和赋值操作

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

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://xiahunao.cn/news/3021896.html

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

相关文章

C++贪心算法

关于string的系统函数&#xff01; &#xff08;注&#xff1a;以下函数只可用于string&#xff0c;不适用其他类型的变量&#xff09; ① a.size(); 这个系统函数是用来获取这个string变量的长度的&#xff0c;我们通常会新建一个变量来保存他&#xff0c;以便之后使用。 …

新火种AI|马斯克聘用OpenAI泄密者,他们的梁子着实越结越深...

作者&#xff1a;小岩 编辑&#xff1a;彩云 就在最近&#xff0c;昔日就职于OpenAI的工程师Pavel Izmailov正式加入了马斯克的AI团队&#xff0c;他还在自己的推特上大张旗鼓的做着宣传&#xff1a;研究院xai。 AI工程师的跳槽本不值得惊讶&#xff0c;但Pavel的跳槽却在行…

每日OJ题_记忆化搜索①_力扣509. 斐波那契数(四种解法)

目录 记忆化搜索概念和使用场景 力扣509. 斐波那契数 解析代码1_循环 解析代码2_暴搜递归 解析代码3_记忆化搜索 解析代码4_动态规划 记忆化搜索概念和使用场景 记忆化搜索是一种典型的空间换时间的思想&#xff0c;可以看成带备忘录的爆搜递归。 搜索的低效在于没有能够…

(五)JSP教程——response对象

response对象主要用于动态响应客户端请求&#xff08;request&#xff09;&#xff0c;然后将JSP处理后的结果返回给客户端浏览器。JSP容器根据客户端的请求建立一个默认的response对象&#xff0c;然后使用response对象动态地创建Web页面、改变HTTP标头、返回服务器端地状态码…

WP All Import Pro插件下载 - 一键导入,无限可能

在当今快节奏的数字时代&#xff0c;网站内容的更新和管理是每个网站管理员和开发者的日常工作。但是&#xff0c;传统的手动更新方法不仅耗时&#xff0c;而且容易出错。现在&#xff0c;有了WP All Import Pro&#xff0c;这一切都将改变。 WP All Import Pro 是一款专为Wor…

金融人需要什么机遇?中国人民大学与加拿大女王大学金融硕士能为你带来什么?

金融&#xff0c;作为现代经济的核心&#xff0c;为无数有志之士提供了施展才华的舞台。在这个日新月异、风云变幻的时代&#xff0c;金融人需要的机遇既是挑战也是机遇。中国人民大学与加拿大女王大学合作举办的金融硕士项目&#xff0c;正是为金融人量身定制的一次宝贵机遇。…

人工智能实验:人脸检测

一、实现目的&#xff1a; 了解人脸检测的主要方法&#xff1b;了解 detectMultiScale 函数的功能及用法&#xff1b;掌握使用 OpenCV 提供的分类器和检测器进行人脸检测的方法。 二、实验设备&#xff1a; 计算机一台&#xff1b;视觉实验软件环境及资源一套&#xff08;vi…

springcloud报错:Failed to start bean‘webServerStartStop‘

如果你正在使用nacos进行服务注册&#xff0c;然后报一下错误&#xff1a; 那就说明的nacos没有打开&#xff0c;所以找到你的下载nacos的文件夹 好了&#xff0c;错误完美解决~

【bash】笔记

在Shell脚本中&#xff0c;-e 是一个测试运算符&#xff0c;用于检查给定的文件或目录是否存在。 | 是通道符&#xff0c;会把前面的输出给后面作为输入。 sudo tee命令在这里用于同时更新文件和在终端显示输出&#xff08;尽管 > /dev/null 将标准输出重定向到黑洞&…

机器学习:基于TF-IDF算法、决策树,使用NLTK库对亚马逊美食评论进行情绪分析

前言 系列专栏&#xff1a;机器学习&#xff1a;高级应用与实践【项目实战100】【2024】✨︎ 在本专栏中不仅包含一些适合初学者的最新机器学习项目&#xff0c;每个项目都处理一组不同的问题&#xff0c;包括监督和无监督学习、分类、回归和聚类&#xff0c;而且涉及创建深度学…

react状态管理之state

第三章 - 状态管理 随着你的应用不断变大&#xff0c;更有意识的去关注应用状态如何组织&#xff0c;以及数据如何在组件之间流动会对你很有帮助。冗余或重复的状态往往是缺陷的根源。在本节中&#xff0c;你将学习如何组织好状态&#xff0c;如何保持状态更新逻辑的可维护性&…

学习软考----数据库系统工程师22

关系运算 基本的关系代数运算 拓展的关系运算 除&#xff1a;需要S连接中属性为C和D的两个元组都与R连接一样&#xff0c;且在R连接中对应的另外的元素完全一致 总结

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

文章目录 再探拷贝构造函数和重载复制运算符实例化新对象和赋值操作强转为类类型指针和引用时临时对象的生成析构过程 考考你问题答案 再探拷贝构造函数和重载复制运算符 实例化新对象和赋值操作 首先我们写一个类&#xff0c;实现它的拷贝构造并重载赋值运算符。 class Tes…

scala速通(精简版)

1.变量和常量 var name [:VariableType] value // variable val name [:ConstantType] value // constant1.声明变量时&#xff0c;类型可以省略 2.类型定义后就不能修改言 3.变量声明必须有初始值 4.变量&#xff0c;常量分别用var&#xff0c;val声明修饰 2.标识符命名…

C++学习————第十天(string的基本使用)

1、string 对象类的常见构造 (constructor)函数名称 功能说明&#xff1a; string() &#xff08;重点&#xff09; 构造空的string类对象&#xff0c;即空字符串 string(const char* s) &#xff08;重点&#xff09;…

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

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

分割模型Maskformer系列

maskformer&#xff1a;Per-Pixel Classification is Not All You Need for Semantic Segmentation 论文地址&#xff1a;https://arxiv.org/pdf/2107.06278 1.概述 传统的语义分割方法通常采用逐像素分类&#xff08;per-pixel classification&#xff09;&#xff0c;而实…

【C++】滑动窗口:最大连续1的个数

1.题目 2.算法思路 其实在做这道题的时候并不需要真的把0翻转成1&#xff0c;只需要找到最长的子数组且该子数组中0的个数不大于K&#xff0c;就可以了&#xff01; 当然我们首先想到的是暴力穷举法&#xff1a; 找到所有符合题意的子数组&#xff0c;跳出最长的那个就可以了…

词袋法TFIDF

Tf-idf⽂本特征提取 TF-IDF的主要思想是&#xff1a;如果某个词或短语在⼀篇⽂章中出现的概率⾼&#xff0c;并且在其他⽂章中很少出现&#xff0c;则认为此词或者短语具有很好的类别区分能⼒&#xff0c;适合⽤来分类。TF-IDF作⽤&#xff1a;⽤以评估⼀字词对于⼀个⽂件集或…

iphone忘记锁屏密码怎么解锁?这些解锁方法你必须知道!

在使用iPhone的过程中经常会遇到很多问题&#xff0c;比如忘记了iPhone的锁屏密码。面对这样的情况&#xff0c;许多用户可能会感到手足无措。别担心&#xff0c;本文将为您详细介绍iPhone忘记锁屏密码的解锁方法&#xff0c;让您轻松解决这一烦恼。 一、使用iTunes备份恢复 如…