我尝试阅读一些有关对象所有权的文章,以及在复制构造一个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()正文中使用了多少次。 如何运作?
答案 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();
}