我这里有一条线:
someSTLVector.push_back(SomeClass(...));
我希望构建什么SomeClass
并将其移动到向量的后面,没有任何副本。然而,破坏者被叫到这里。我试着用std::move
来修改这个
someSTLVector.push_back(std::move(SomeClass(...)));
但结果并没有改变。
我还尝试在SomeClass
中定义以下内容
SomeClass(SomeClass&&) = default;
SomeClass& operator= (SomeClass&&) = default;
SomeClass(const SomeClass&) = delete;
SomeClass& operator= (const SomeClass&) = delete;
这也没什么用,破坏者还在被叫。请注意,SomeClass
包含作为成员的引用。
很明显,SomeClass
被构造,然后复制到向量中。我不想避免这种情况,并将其构造为向量的一部分(或者至少移到向量中,避免任何复制)。SomeClass
管理在析构函数中释放的资源。如果在复制对象时调用析构函数,则释放资源,该对象将变得无效,指向不再存在的资源。
如何实例化一个类,其中生成的对象将放置在向量的后面,但不会在过程中复制(从而销毁)?
发布于 2020-02-20 17:06:38
I希望构建什么SomeClass并将其移动到向量的后面,没有任何副本。
事情就是这样发生的。
然而,
在这里调用了析构函数。
确实如此。这将是传递给移动构造函数的临时对象:
someSTLVector.push_back(SomeClass(.));^
有用于初始化临时对象的语法。
很明显,SomeClass被构造,然后复制到向量中。
准确地说是搬家了。虽然移动是一种复制形式。
我不想避免这种情况,并且让它作为向量的一部分来构造(或者至少移到向量中,避免任何复制)。
你已经设法避免了复制。为了避免移动,可以使用emplace_back
成员函数而不是push_back
someSTLVector.emplace_back(...);
这将直接将参数传递给元素的构造函数。
如果在复制对象时调用析构函数,则释放该资源,该对象将变得无效,指向不再存在的资源。
如果析构函数释放了一些资源,那么默认的移动构造函数/赋值可能没有执行您希望它们做的事情。见五/三规则。
发布于 2020-02-20 17:07:30
被移动的对象仍将被销毁。因此,您的SomeClass
可能被移动到向量中(您可以在move构造函数中添加一个std::cout <<
消息以进行验证),但它随后也会被销毁。
您可以调用std::vector::emplace_back
将项目构造到向量中。但是,这仍然不能保证您的对象不会被移动(例如,如果向量需要增长,它可以分配更多的空间,然后将所有对象移动到新的存储空间,然后在它们原来的位置销毁它们)。
如果您在析构函数中释放了一些资源,则需要确保在对象被移动时不执行该发布。通常情况下,将构造函数“空”从移出的对象中移出(例如,在该方法中给定SomeClass(SomeClass&& other)
,可以将other
修改为“空它”)。然后,您的析构函数可以查看它是否为“空”(已从其中移出),而不释放您所持有的任何资源。
https://stackoverflow.com/questions/60330663
复制