函数返回的临时unique_ptr的句柄

时间:2018-06-21 05:17:53

标签: c++ constructor copy move unique-ptr

我尝试阅读一些有关对象所有权的文章,以及在复制构造一个unique_ptr时(本质上是禁止的)时如何应用一些例外情况。当然,我会通过并通过引用将其返回,因此无需进行复制。

std::unique_ptr<T>& ptr_func(std::unique_ptr<T>& p) {
    return p;
}

将指针的实例传递给此函数是没有问题的。无论它指向什么,它基本上都会进入函数,而不会改变。

现在是我的问题:假设我感兴趣的指针指向包含多个属性的对象,而我只能以函数返回值的形式检索该指针,例如。

std::unique_ptr<T>& ptr_func() //say this function returns my pointer.

现在,假设要花很多时间才能检索到该指针(例如,通过遍历大向量),并且我想设置/获取它指向的对象的许多不同属性。然后,对于每个单独的动作,无法拥有第二个(临时)指向其所指向的指针或对象的句柄变得非常不切实际,因为我必须调用返回指针的函数。在某种已知情况下,编译器确实以某种方式创建了第二个引用:假设我传递了将我的指针作为参数传递给另一个函数的函数,该函数改变了所指向对象的属性:

void set_attributes(std::unique_ptr ptr) {
    ptr->change_something();
    ptr->change_something_else();
}

像这样:

void set_attributes(function_returning_pointer())

在这种情况下, function_returning_pointer()仅被调用一次,无论其返回值在 set_attributes()正文中使用了多少次。 如何运作?

1 个答案:

答案 0 :(得分:0)

std::unique_ptr<T>& ptr_func()是一个奇怪的签名:您可能会拥有所有权...或不会。

您可能需要更清晰的功能:

T& get_ref();
T* get_ptr();
std::unique_ptr<T> take();

根据您的使用情况,set_attributes应该是:

void set_attributes(MyObject& ptr) {
    ptr.change_something();
    ptr.change_something_else();
}

用法类似于

assert(function_returning_pointer() != nullptr);
set_attributes(*function_returning_pointer());

assert(get_ptr() != nullptr);
set_attributes(*get_ptr());

set_attributes(get_ref());

auto ptr = take();
assert(ptr != nullptr);
set_attributes(*ptr); // set_attributes(*take()) would be useless as object would be destroyed.

如果您确实想继续传递unique_ptr而不转让所有权,那么您的方法将是:

void set_attributes(std::unique_ptr<MyObject>& ptr) { // prefer MyObject& or MyObject* instead
    assert(ptr != nullptr);
    ptr->change_something();
    ptr->change_something_else();
}