返回信息流为什么下面的测试代码显示,只有构造函数被调用了,而拷贝构造函数和赋值操作符没有被调用?
按照语句的语义,代码应该等价于:
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.
这是一条镜像帖。来源:北邮人论坛 / cpp / #46430同步于 2010/11/19
该镜像源已超过 30 天没有更新,可能在源站已被删除。
CPP机器人发帖
[求助]关于类的拷贝构造函数和赋值运算符
bupteinstein
2010/11/19镜像同步4 回复
订阅后,新回复会通过你的通知中心匿名送达。
4 条回复
按理说,是先构造,再拷贝构造。但编译器可以优化
【 在 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.
A a;
A b(a);//调用拷贝构造函数
或
A b=a;//仍然调用拷贝构造函数
A a;
A b;
b=a;//这样才能调用赋值运算符
所以你那个程序无论如何都不可能调用到赋值运算符
而拷贝构造函数首先是一个构造函数,一个特殊的构造函数,应该先调用构造函数,然后才是拷贝...
或许,就像1楼说的,编译器为了效率优化掉了...
【 在 bupteinstein (相期以茶) 的大作中提到: 】
: 为什么下面的测试代码显示,只有构造函数被调用了,而拷贝构造函数和赋值操作符没有被调用?
: 按照语句的语义,代码应该等价于:
: TestCtor tmp1(1);
: ...................
拷贝构造和赋值的区别是:
拷贝构造也是构造函数,用来初始化一个新对象。这是对象从无到有。
赋值是对已经存在的对象进程操作,就是“已存在的对象”从一种状态变化到另一种状
态。
所以你的程序没有赋值操作。
【 在 bupteinstein (相期以茶) 的大作中提到: 】
: 为什么下面的测试代码显示,只有构造函数被调用了,而拷贝构造函数和赋值操作符没有被调用?
: 按照语句的语义,代码应该等价于:
: TestCtor tmp1(1);
: ...................