首先OP的代码进行审查。我稍微修改了一下,以便更明显地发生。
#include <iostream>
using namespace std;
static int allocCounter = 0;
class TestCopy
{
private:
string pStr;
int counter;
public:
TestCopy(const TestCopy &obj)
{
allocCounter++;
counter = allocCounter;
cout << "copy construct " << counter << endl;
pStr = obj.pStr;
}
TestCopy(const string &test)
{
allocCounter++;
counter = allocCounter;
cout << "string construct " << counter << endl;
pStr = test;
}
~TestCopy()
{
cout << counter << "\t" << pStr << endl;
}
TestCopy get()
{
TestCopy x = *this; // copy constructed
return TestCopy(x); // copy constructed and copy elision
}
string getStr()
{
return pStr;
}
TestCopy & operator=(const TestCopy &obj)
{
cout << "assigned " << obj.counter << " to "<< counter << endl;
pStr = obj.pStr;
// counter = obj.counter; deliberately left out
return *this;
}
};
int main()
{
string xstr = "test";
TestCopy x(xstr); // string constructed
TestCopy x2 = x.get(); // Would be a copy constructed if not for copy elision
return 0;
}
输出
string construct 1
copy construct 2
copy construct 3
2 test
3 test
1 test
注意即使TestCopy x=*this;
好吧赋值操作符的呼叫。现在我们该如何砍掉一些呢?
首先我们得到get
TestCopy get()
{
return *this; // copy constructed. Or is it? The copy construction could
// happen at the caller. Either way it is copied and elided
}
输出
string construct 1
copy construct 2
2 test
1 test
所以去掉冗余副本在这一点上,我们知道有没有必要获取复制或分配,因为return语句会为我们做。这是关于OP的问题的重要部分。
但是,如果我们改变main
了一下,添加一个赋值运算符,我们可以看到一个更有趣的行为。
int main()
{
string xstr = "test";
TestCopy x(xstr); // string constructed
TestCopy x2(""); //string constructed
x2 = x.get(); // assigned and a copy construct when returning from get
cout << "done main" << endl;
return 0;
}
输出
string construct 1
string construct 2
copy construct 3
assigned 3 to 2
3 test
done main
2 test
1 test
从get
返回被分配到x2
,然后销毁。 x2
被破坏,最后x
。
的问题是,这些都不'TestCopy'are的动态分配的,所以当超出范围,他们被摧毁。 – Rodolfo
你必须明确地说,你正在函数签名'TestCopy&get(){'注意到'''我添加了 – Rodolfo
并不完全正确,@Rodolfo。Copy elision会在返回问题时处理复制构造,并且返回本地作为参考将在MohsenTi的面部爆炸,因为返回的引用不再存在。 Moe on copy elision:http://stackoverflow.com/questions/12953127/what-are-copy-elision-and-return-value-optimization – user4581301