问题描述
- 大神帮看一下代码,为什么t5 = addC(a1, a2)中,只调用了一次copy构造函数?
-
#include<iostream> using namespace std; class ABC { public: ABC(int a = 0, int b = 0) { this->a = a; this->b = b; printf("我是有参构造函数!n"); } ABC(ABC &c) { this->a = c.a; this->b = c.b; printf("我是copy构造函数!n"); } //成员函数 ABC addC(ABC &c) { //1.实例化t1 //2.实例化匿名对象 //3.t1调用构造函数给匿名对象赋值 //4.ti被析构 ABC t1(this->a + c.a, this->b + c.b); return t1; } ABC& addC2(ABC &c)//返回一个引用,相当于自身 { this->a = this->a + c.a; this->b = this->b + c.b; return *this; //把*(&调用者)回到了调用者元素 } //成员函数 void PrintABC() { printf("t2->a:%d,t2->b:%dn", this->a, this->b); } ~ABC() { printf("我是析构函数!n"); } public: int a; int b; }; //全局函数 //成员函数 转为全局函数 多了一个参数 void PrintABC(ABC *t2) { printf("t2->a:%d,t2->b:%dn", t2->a, t2->b); } //全局函数 //全局函数转成 成员函数 少了一个参数 ABC addC(ABC &c, ABC &d) { //1.实例化temp //2.实例化匿名对象 //3.temp调用构造函数给匿名对象赋值 //4.temp被析构 ABC temp(c.a + d.a, c.b + d.b); return temp; } void main() { ABC a1(1, 2); ABC a2(3, 4); ABC a3; //全局函数方法 a3 = addC(a1, a2); //成员函数方法 { ABC a4 = a1.addC(a2); //匿名对象直接转化为 t4(直接转化,不调用copy构造函数) a4.PrintABC(); ABC t5; printf("=====================n"); t5 = addC(a1, a2);//匿名对象赋值给t5 t5.PrintABC(); } system("pause"); }
解决方案
John_ToString 你理解过了吧。这里没那么复杂,而且楼主也就是测试,应该编译的是debug版,不存在优化。addC函数内定义了一个temp对象,这个对象是用构造函数直接构造的,不需要调用拷贝构造。当函数范围时 把temp赋值给t5调用了一次拷贝构造。
如果真的是优化,编译的代码中不会有temp对象,而会用t5替换之。
另外楼主需要理解什么事拷贝构造函数以及什么时候会调用,这样你就会豁然开朗。
解决方案二:
t5 = addC(a1, a2);//匿名对象赋值给t5 这句话是不是有问题啊
解决方案三:
实例化temp的时候是有参构造咯,然后函数返回值赋值给t5就是copy构造咯
解决方案四:
ABC addC(ABC &c)
{
//1.实例化t1
//2.实例化匿名对象
//3.t1调用构造函数给匿名对象赋值
//4.ti被析构
ABC t1(this->a + c.a, this->b + c.b);
return t1;
}
返回值应该是匿名对象,这个匿名对象不应该用copy构造函数赋值吗。
解决方案五:
且不看你的所有代码,就看你所说的点,首先参数是引用不会调用拷贝构造,进入函数体之后,掉一次构造,然后函数返回(因为返回的是对象)后经过
编译器优化后只调用一次拷贝构造,即就是直接用此对象去初始化t5这个对象,省去了编译器构造临时对象的过程,为什么呢?原因是编译器为了提高效
率,而当前的对象已经被构造出来并且放在某个寄存器或者缓存里面,编译器就不会再去访问此对象的内存空间,这样子效率提高了很多,但又会引发一
些其他的问题,尤其是在写网络通信以及端口方面的软件时,应该注意,应该尽可能的去制止编译器因为一味提高效率而牺牲准确性的可能性,因此c++
提出了voliate关键字,具体请自己去查阅相关文档...
解决方案六:
有空上机看看你的这段代码
时间: 2024-10-06 20:08:40