如何返回对象而不创建该对象的副本
how to return object without create copy of that?
我开发了一个简单的c++类来测试c++对象何时破坏;现在我有一个问题,当一个对象通过函数返回时,c++创建一个新对象并返回,当返回引用销毁对象时,我的错误是什么?
下面附上一个简单的类。
#include <iostream>
using namespace std;
static int freeCounter=0;
class TestCopy {
private:
string pStr;
public:
TestCopy(const TestCopy &obj){
pStr=obj.pStr;
}
TestCopy(string &test){
pStr=test;
}
~TestCopy(){ freeCounter++; cout << freeCounter <<"t" << pStr << endl; }
TestCopy get(){
TestCopy x=*this;
return TestCopy(x); // -> TestCopy(x) is first destroy in result
}
string getStr(){
return pStr;
}
};
int main(){
string xstr="test";
TestCopy x(xstr); // x is third destroy
TestCopy x2=x.get(); // x2 is second destroy
cout << x.getStr() << endl;
return 0;
}
和结果
1 test
test
2 test
3 test
x是一个本地对象,当函数结束时,x将被销毁。
因此,x是第一个被破坏的。
首先回顾一下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
因此,在这一点上,我们知道没有必要在get中复制或赋值,因为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
,然后被销毁。CCD_ 6被破坏,最后CCD_。
感谢@shipman的帮助,我发现了我的错误。通过更改
TestCopy x=*this;
带有
const TestCopy &x=*this;
问题已解决
相关文章:
- 如何为模板化对象创建模板向量?VS正在投掷C3203
- 具有包含其他对象的类的对象创建顺序
- 为什么我们再次从结构对象创建结构变量?
- 将对象创建为全局/静态对象会崩溃,而本地对象不会崩溃
- 如何创建一个对象创建函数,该函数将由与其关联的名称调用?
- 如何为自定义模板对象创建专门的函数模板
- 对象创建错误的C++矢量
- 如何为Python Swigged C++对象创建和分配回调函数
- 在 C++ 中为 C 样式对象创建一个透明包装类
- 此类模板的对象创建如何工作?
- C++ 中的对象创建类型有什么区别?
- 未知大小的数组作为类成员,用于在运行时(对象创建时间)创建数组的对象
- 如何仅通过父类对象限制对象创建
- 在正确性或良好的代码结构方面,这种动态对象创建看起来如何
- 无法将类对象创建为另一个类的成员
- 如何从现有基类对象创建派生类对象
- 在 DTor 之前删除的静态对象创建的线程?
- C++:定义多个构造函数时的对象创建/销毁序列
- 从对象创建矢量包装器,该对象只允许使用索引访问向量
- 是否可以为CPP中的对象创建一组指针