首页 > 其他分享 >编译器绕过拷贝构造函数和返回值优化

编译器绕过拷贝构造函数和返回值优化

时间:2023-05-31 16:11:15浏览次数:44  
标签:string temp 构造 Person 编译器 返回值 拷贝 构造函数

写在前面:

在拷贝初始化(也就是用等号初始化,注意使用拷贝构造函数创建一个新的对象不属于拷贝初始化)过程中,编译器可以(但不是必须)跳过拷贝构造函数或者移动构造函数,直接创建对象。

1 string null_book="999";
2 //可以改写为
3 string null_book("999");

这里面”999“隐式的转换为string对象,例如:string temp("999");,然后执行拷贝构造函数:string null_book=temp;

但是者里面的拷贝构造被忽略掉了。

这里面举个黑马程序员的例子:

 1 class Person
 2 {
 3 public:
 4     Person()
 5     {
 6         cout << "Person的默认构造函数调用" 
 7             << "地址为:"
 8             << this
 9             << endl;
10     }
11     Person(int age):age_(age)
12     {
13         cout << "Person有参构造函数调用" 
14             << "地址为:"
15             << this
16             << endl;
17     }
18     Person(const Person& p)
19     {
20         cout << "Person的拷贝构造函数调用" 
21             <<"地址为:"
22             <<this
23             << endl;
24         
25     }
26     ~Person()
27     {
28         cout << "Person的析构函数调用" 
29             << "地址为:"
30             << this
31             << endl;
32     }
33     int age_;
34 };
35 
36 Person dowork()
37 {
38     Person p3;
39     return p3;
40 }
41 void test03()
42 {
43     Person p4 = dowork();
44 }
45 
46 int main()
47 {
48     test03();
49     system("pause");
50     return 0;
51 }

运行结果为:

 在没有运行之前个人猜测运行结果会是这样的:

首先p3在创建的时候会调用默认构造。

然后在运行return语句的时候系统会创建一个临时的对象temp会接收到p3此时调用拷贝构造

然后将p3析构掉

然后,在test03函数中Person p4 = dowork();会调用拷贝构造函数,将temp拷贝给p4

然后当test03执行结束后会析构掉p4。

(这里面我有个问题就是temp什么时候被析构掉呢,黑马程序员的代码中也没有解释p'何时被析构掉,我想这个应该是返回值的知识,也就是返回的时候创建这个临时的temp的生命周期到底是多久,是在调用点将值传递给接收的变量吗)。

然而运行结果却只有默认构造和它的析构也就是对象p3。

这里面在返回的时候编译器采用了返回值优化,也就是没有创建那个临时的对象temp,是直接将p3复制到了test03中的p4的内存空间中去了因此这一次的拷贝构造就没了,然后执行Person p4 = dowork();时采用的是拷贝初始化,这个地方也不会调用拷贝构造,所以这一步也没有发生拷贝构造。

以上是个人的理解

再来看一个例子:

也就是对象在值传递的时候会发生拷贝构造,注意这里是实参赋值给形参发生的拷贝构造,不是拷贝初始化。

 1 class Person
 2 {
 3 public:
 4     Person()
 5     {
 6         cout << "Person的默认构造函数调用" 
 7             << "地址为:"
 8             << this
 9             << endl;
10     }
11     Person(int age):age_(age)
12     {
13         cout << "Person有参构造函数调用" 
14             << "地址为:"
15             << this
16             << endl;
17     }
18     Person(const Person& p)
19     {
20         cout << "Person的拷贝构造函数调用" 
21             <<"地址为:"
22             <<this
23             << endl;
24         
25     }
26     ~Person()
27     {
28         cout << "Person的析构函数调用" 
29             << "地址为:"
30             << this
31             << endl;
32     }
33     int age_;
34 };
35 void test02(Person p2)
36 {
37 
38 }
39 
40 int main()
41 {
42     Person p1;
43     test02(p1);
44     system("pause");
45     return 0;
46 }

 

标签:string,temp,构造,Person,编译器,返回值,拷贝,构造函数
From: https://www.cnblogs.com/Sandals-little/p/17446441.html

相关文章

  • 最小编译器和 UI 框架「GitHub 热点速览」
    如果有一个关键词来概述本周的GitHub热门项目的话,大概就是van和sectorc都用到的smallest。只不过一个是前端的响应式框架,一个是搞编译的C编译器。它们除了轻量化这个共同特点之外,还有好用,足以满足你的日常编程所需。说到编程,EasySpider便是一个免去敲代码工作量,用看得......
  • "以API接口快速获得aliexpress速卖通商品详情-返回值说明
     为了方便商家获取速卖通上的商品信息,速卖通提供了API接口来获取商品数据。本文将介绍如何通过API接口获取速卖通商品数据。一、申请API接口权限在使用API接口前,首先需要在速卖通官网注册账号并通过实名认证。然后,在个人资料页面找到开发者中心,申请API接口权限。在申请权限时,需要......
  • 结构体就算不用构造函数也可以初始化
    标题结构体就算不用构造函数也可以初始化#include<iostream>#include<vector>#include<algorithm>#include<string>#include<queue>#include<set>usingnamespacestd;structstateAndLevel{ stringstr; intlevel;};queue<stateAndLevel>......
  • 【python】函数返回值,返回多个值(返回元组)
    函数返回值,返回多个值(返回元组)实例1:#定义函数,有多个返回值(返回元组)defmeasure():"""测量温度和湿度"""print("测量开始...")temp=39wetness=50print("测量结束...")#元组-可以包含多个数据,因此可以使用元组让函数一次返回多个值......
  • sse 与 编译器自动优化
    directx形式的矩阵和向量计算代码在编译的时候是自动汇编为sse汇编的何时使用手写sse指令呢,当你的应用程序需要写一些物理运算时候可以使用自己编写的sse计算函数来为3维运算加速关于amd指令集(3dnow)有的程序在编写的时候可以使用判断来判断是否是amd平台的cpu如果上了......
  • codon-基于LLVM的python编译器
    安装目前只linux和mac系统。从https://github.com/exaloop/codon下载最新版进行安装。然后设置环境变量:exportPATH=~/.codon/bin:$PATHexportCODON_PYTHON=/usr/lib/libpython3.10.so上述路径换成自己的系统路径。下面的示例代码(goldbach.codon):importmathdefprime(n)......
  • 通过实际的例子,介绍编译器的工作过程
    本文详细介绍下面这张图。编译器是将高级语言代码翻译为机器语言代码的工具。编译器的工作可以划分为多个重要阶段,以下是其中几个常见的阶段,并给出了具体例子:词法分析(LexicalAnalysis):在词法分析阶段,编译器将源代码分解成词法单元(Token)序列。词法单元是语法上具有意义的最小......
  • 委托构造函数
    一.当构造受委托的构造函数时,受委托的构造函数函数体会执行而委托构造函数函数体不会执行;classPerson{public:Person(){cout<<"这是一个无参构造"<<endl;}Person(constPerson&p){cout<<"这是一个拷贝构造"<<endl;......
  • MyBatis之返回值处理
    MyBatis之返回值处理1、返回值为基本数据类型当我们的SQL语句执行结束,要返回的类型为基本数据类型的时候,直接写你要返回的类型即可<insertid="addUser"parameterType="com.liu.pojo.User">insertintotb_uservalues(null,#{username},#{password});</insert>......
  • js原型prototype(实例构造函数的属性) __proto__(实例对象的属性) constructor(实例
    functionPerson(name,age){this.name=namethis.age=age}Person.prototype.sayHi=function(){//原型是公共方法解决构造函数new对象公共属性和方法的内存浪费console.log(this.name+'sayhi!!')}constp1=newPerson('aa',12)constp2=new......