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

时间:2018-09-25 17:16:20

标签: c++ scope

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

例如,我的 main.cpp

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

container.h

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

item.h

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

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

是否有一些惯用的方式在范围内创建对象并将它们“转移”到另一个类?

2 个答案:

答案 0 :(得分:1)

  

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

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

std::vector<Item> items;

然后,当通过值传递时,需要将对象移动到矢量中:

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() );
}

答案 1 :(得分:1)

有几种方法可以解决此问题。基本上,这是传递xvalue的确切用例。按值传递将导致项的所有成员的副本。如果某些成员可能在堆上分配了大量数据,例如std :: vector,则需要通过移动成员来避免这种复制和分配。

简单的答案就是忽略斯科特·迈耶斯(Scott Meyers)所说的“通用参考”

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