对象超出范围/转让所有权

Object going out of scope / transferring ownership

本文关键字:所有权 范围 对象      更新时间:2023-10-16

我在创建对象、将它们添加到容器类以及让它们超出C++范围时遇到问题。

举个例子,我的主要.cpp

Container container;
for (unsigned int i = 0; i < 10; i++) {
Item item;
container.add_item(item);
}

和容器的界面

struct Container {
std::vector<std::reference_wrapper<Item>> items;
void add_item(Item& item); // Push back of items vector.
};

项目.h

struct Item {
std::unique_ptr<AnotherThing> unrelated_thing;
};

问题出现在我的主要类中,在 for 循环中创建的容器已经超出了范围。如果我将add_item更改为按值传递,则会给我带来unique_ptr和复制构造函数的问题。

是否有一些惯用的方法可以在作用域内创建对象并将它们"转移"到另一个类?

如果我将add_item更改为按值传递,则会给我带来unique_ptr和复制构造函数的问题。

您的向量需要按值保存对象:

std::vector<Item> items;

然后,当按值传递时,您需要将对象移动到 Vector 中:

void Container::add_item( Item item )
{
items.push_back( std::move( item ) );
}

然后你还需要在循环中移动你的对象:

for (unsigned int i = 0; i < 10; i++) {
Item item;
container.add_item( std::move(item) );
}

或者你可以简单地通过临时:

for (unsigned int i = 0; i < 10; i++) {
container.add_item( Item() );
}

有几种方法可以解决这个问题。这基本上是传递 xvalues 的确切用例。按值传递将导致项的所有成员的副本。如果存在可能在堆上分配大量数据的成员(例如 std::vector(,您将希望通过移动成员来避免这种复制和分配。

简单的答案是绕过斯科特·迈耶斯所谓的"通用参考"。

void Container::add_item( Item&& item) {
items.push_back( std::move(item))
}