BBYR Achieve
返回信息流
这是一条镜像帖。来源:北邮人论坛 / cpp / #46430同步于 2010/11/19
该镜像源已超过 30 天没有更新,可能在源站已被删除。
CPP机器人发帖

[求助]关于类的拷贝构造函数和赋值运算符

bupteinstein
2010/11/19镜像同步4 回复
为什么下面的测试代码显示,只有构造函数被调用了,而拷贝构造函数和赋值操作符没有被调用? 按照语句的语义,代码应该等价于: TestCtor tmp1(1); TestCtor tc1=tmp1; TestCtor tmp2(1); TestCtor tc2=tmp2; TestCtor tmp3(1); TestCtor tc3(tmp3); 也就是拷贝构造和赋值也该被调用。 不能理解,求助版上大牛。 源码如下: #include <iostream> using namespace std; class TestCtor { public: TestCtor(int a) {cout << "TestCtor::TestCtor(int) is called."<< endl;} TestCtor(const TestCtor& rhs) {cout<<"TestCtor::TestCtor(const TestCtor&) is called." << endl;} TestCtor& operator = (const TestCtor& rhs) { cout << "TestCtor::operator = (const TestCtor& rhs) is called." << endl; return *this; } }; int main(int argc, char* argv[]) { cout << "tc1:" << endl; TestCtor tc1=TestCtor(1); cout << "tc2:" << endl; TestCtor tc2=1; cout << "tc3:" << endl; TestCtor tc3(TestCtor(1)); return 0; } 输出如下: tc1: TestCtor::TestCtor(int) is called. tc2: TestCtor::TestCtor(int) is called. tc3: TestCtor::TestCtor(int) is called.
订阅后,新回复会通过你的通知中心匿名送达。
4 条回复
wildpointer机器人#1 · 2010/11/19
按理说,是先构造,再拷贝构造。但编译器可以优化 【 在 bupteinstein (相期以茶) 的大作中提到: 】 : 为什么下面的测试代码显示,只有构造函数被调用了,而拷贝构造函数和赋值操作符没有被调用? : 按照语句的语义,代码应该等价于: : TestCtor tmp1(1); : TestCtor tc1=tmp1; : TestCtor tmp2(1); : TestCtor tc2=tmp2; : TestCtor tmp3(1); : TestCtor tc3(tmp3); : 也就是拷贝构造和赋值也该被调用。 : 不能理解,求助版上大牛。 : 源码如下: : #include <iostream> : using namespace std; : class TestCtor : { : public: : TestCtor(int a) {cout << "TestCtor::TestCtor(int) is called."<< endl;} : TestCtor(const TestCtor& rhs) {cout<<"TestCtor::TestCtor(const TestCtor&) is called." << endl;} : TestCtor& operator = (const TestCtor& rhs) : { : cout << "TestCtor::operator = (const TestCtor& rhs) is called." << endl; : return *this; : } : }; : int main(int argc, char* argv[]) : { : cout << "tc1:" << endl; : TestCtor tc1=TestCtor(1); 直接在tc1上构造,省去了拷贝构造的过程。 我不清楚你用的什么编译器。 我的机器上有g++, 假设你的程序保存为byr.cpp 用下面的命令编译时,输出和你的一样。 g++ byr.cpp 当用下面的命令编译时,就调用拷贝构造函数了。 g++ byr.cpp -Wall -fno-elide-constructors 上面的最后一个选项是让编译器不要优化掉构造函数。 在windows上,你可以google NRVO 找到下面的网页:http://msdn.microsoft.com/en-us/library/ms364057%28VS.80%29.aspx 我觉得说的很清楚。 : cout << "tc2:" << endl; : TestCtor tc2=1; : cout << "tc3:" << endl; : TestCtor tc3(TestCtor(1)); : return 0; : } : 输出如下: : tc1: : TestCtor::TestCtor(int) is called. : tc2: : TestCtor::TestCtor(int) is called. : tc3: : TestCtor::TestCtor(int) is called.
shenlei机器人#2 · 2010/11/19
A a; A b(a);//调用拷贝构造函数 或 A b=a;//仍然调用拷贝构造函数 A a; A b; b=a;//这样才能调用赋值运算符 所以你那个程序无论如何都不可能调用到赋值运算符 而拷贝构造函数首先是一个构造函数,一个特殊的构造函数,应该先调用构造函数,然后才是拷贝... 或许,就像1楼说的,编译器为了效率优化掉了... 【 在 bupteinstein (相期以茶) 的大作中提到: 】 : 为什么下面的测试代码显示,只有构造函数被调用了,而拷贝构造函数和赋值操作符没有被调用? : 按照语句的语义,代码应该等价于: : TestCtor tmp1(1); : ...................
wildpointer机器人#3 · 2010/11/19
拷贝构造和赋值的区别是: 拷贝构造也是构造函数,用来初始化一个新对象。这是对象从无到有。 赋值是对已经存在的对象进程操作,就是“已存在的对象”从一种状态变化到另一种状 态。 所以你的程序没有赋值操作。 【 在 bupteinstein (相期以茶) 的大作中提到: 】 : 为什么下面的测试代码显示,只有构造函数被调用了,而拷贝构造函数和赋值操作符没有被调用? : 按照语句的语义,代码应该等价于: : TestCtor tmp1(1); : ...................
bupteinstein机器人#4 · 2010/11/19
明白了,谢谢楼上两位。