我试图了解如何在C++中正确地对所有权建模,而我难以准确地了解谁何时拥有什么。
例如,我有一个这样的类,它具有非常复杂的初始化列表,而复杂的成员也具有复杂的初始化列表。
class ComplexClass {
public:
OtherComplexClass1 foo1;
OtherComplexClass2 foo2;
//...
OtherComplexClassN fooN;
ComplexClass(
int arg1, int arg2, int arg3) :
foo1(OtherComplexClass1{arg1,arg2}),
foo2(OtherComplexClass2{arg3}),
//...
fooN(OtherComplexClassN{foo1,foo2,foo3,foo4})
{};
};
使用这个我可以像这样分配auto my_class = ComplexClass(1,2,3);
并使用该类的罚款。但是现在我想动态生成这些,所以我尝试了auto my_vec = std::vector<ComplexClass>{};
my_vec.emplace_back(ComplexClass{1,2,3});
但是这样做我有很多内存错误。当我改为auto my_vec = std::vector<std::unique_ptr<ComplexClass>>{};
my_vec.emplace_back(std::make_unique<ComplexClass>(1,2,3));
一切似乎都正常。我的问题是,为什么第二种方法有效,而不是第一种有效?谢谢
编辑:
(1)我实际上有两种情况。一是我所描述的
auto my_vec = std::vector<ComplexClass>{};
my_vec.emplace_back(ComplexClass{1,2,3});
带有自由功能中的代码(catch2测试)。另一个是我实际上拥有以上内容的地方,但是在持有类的构造函数中。
在第一种情况下
==60617==ERROR: AddressSanitizer: heap-use-after-free
指示其中一个复杂类的成员函数。在第二种情况下,我得到==60565==ERROR: AddressSanitizer: heap-use-after-free
,指示复杂类之一的std::dequeue
成员。(2)ComplexClass和OtherComplexClassK树深入了几层,并且树中某处的许多成员是对该树中其他成员的引用。也许这就是问题所在?我确保所有引用都是对最终在init列表中构造的成员的引用。
到目前为止,这些评论非常有帮助。
最佳答案
您的类(class)应该是默认可构造的,可复制分配的和可复制构造的。查看此答案:https://stackoverflow.com/a/33110129/5132939了解更多详细信息。另外,还希望使其可移动且可移动。在某些情况下,std::vector将使用移动语义而不是复制。
关于c++ - C++ vector 拥有对象的所有权,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63105772/