我遇到了一个有趣的问题。我在 C++ 中有一个函数,它返回一个充满类的向量。返回向量后,它会为向量中的每个元素调用解构器。
问题很明显:数据在类指向指针的地方被销毁,当对象被销毁时这些指针被释放。我只能假设调用解构函数是因为向量在堆栈上,而不是在堆上。
所以问题是:
无论如何要继续从函数返回向量,而不会被破坏?或者我是否必须传递一个指针以返回向量作为函数的输入?
我遇到了一个有趣的问题。我在 C++ 中有一个函数,它返回一个充满类的向量。返回向量后,它会为向量中的每个元素调用解构器。
问题很明显:数据在类指向指针的地方被销毁,当对象被销毁时这些指针被释放。我只能假设调用解构函数是因为向量在堆栈上,而不是在堆上。
所以问题是:
无论如何要继续从函数返回向量,而不会被破坏?或者我是否必须传递一个指针以返回向量作为函数的输入?
您可以使用new
. 您不应该从函数中给出对堆栈对象的引用,因为它们将在函数完成后立即被销毁。
如果您希望您的函数按值返回向量,请确保向量内的对象实现复制构造函数(也许还有赋值运算符,对此不确定)。有了这个,请不要忘记三法则。
C++11 应该使用右值引用解决您的问题。老实说,我自己没有尝试过,但是从我读到的内容来看,它将完全按照您的要求返回向量而不破坏和重新创建它(通过将该向量分配的内存传递给新向量而不是让新向量创建自己的内存并从旧向量复制内容)。
C++ 向量在堆上分配。当您按值返回向量时,将创建一个包含所有元素副本的新向量,然后原始元素将被销毁。
听起来您没有正确定义复制构造函数。例如:
class ThisIsWrong
{
public:
ThisIsWrong()
{
i = new int;
*i = rand();
}
~ThisIsWrong()
{
delete i;
i = nullptr;
}
int value() const
{
return *i;
}
private:
int* i;
};
void foo()
{
vector<ThisIsWrong> wronglets;
wronglets.push_back(ThisIsWrong());
return wronglets;
}
void main()
{
vector<ThisIsWrong> w = foo();
w[0].value(); // SEGFAULT!!
}
您要么需要删除复制和赋值构造函数(然后将其变成编译错误而不是运行时),要么正确实现它们。