Tom*_*zyk 20 c++ smart-pointers unique-ptr c++14
#include <memory>
class bar{};
void foo(bar &object){
std::unique_ptr<bar> pointer = &object;
}
Run Code Online (Sandbox Code Playgroud)
我想将对象的地址分配给指针.上面的代码显然不会编译,因为赋值运算符的右侧需要是std :: unique_ptr.我已经尝试过了:
pointer = std::make_unique<bar>(object)
Run Code Online (Sandbox Code Playgroud)
但它在编译过程中会抛出许多错误.我怎样才能做到这一点?
更新
如答案中所述 - 使用该std::unique_ptr::reset方法导致未定义的行为.现在我知道,在这种情况下我应该使用标准指针.
Ray*_*nda 15
void foo(bar &object){
std::unique_ptr<bar> pointer;
pointer.reset(&object);
}
Run Code Online (Sandbox Code Playgroud)
但请注意,不建议这样做,不应创建unique_ptr传递给函数的引用.在函数结束时,当pointer它被销毁时,它也会尝试销毁object,并且它不会在函数调用之外可用,从而导致访问内存错误.
示例:这将编译,但会给出运行时错误.
struct bar{ int num;};
void foo(bar &object){
std::unique_ptr<bar> pointer;
pointer.reset(&object);
}
int main()
{
bar obj;
foo(obj);
obj.num; // obj is not a valid reference any more.
return 0;
}
Run Code Online (Sandbox Code Playgroud)
另一方面,您可能需要考虑使用shared_ptr这可以帮助您决定:unique_ptr还是shared_ptr?.
小智 7
请允许我让你失望,但你不会。您有一个引用,它可以指向动态分配的对象或堆栈分配的对象,或者可能指向动态分配的数组中的对象,该对象不是单独分配的。
\n\n您希望将其地址放入一个类中,该类将自动对该地址调用删除。这对于上述大多数情况都是无效的。那是错的。因此,永远不应该传递引用并将引用的地址放入智能指针中。尤其是使用reset() 时更是如此。
\n\n最多,您可能想做的是用新分配的对象初始化智能指针,例如:
\n\nauto ptr = std::unique_ptr<X>(new X(p1, p2));\nRun Code Online (Sandbox Code Playgroud)\n\n切勿获取参考地址。曾经。没原因。这在道德上是错误的。并不是因为引用地址的使用无效,而是因为它可以有效使用;这是因为两个月后,新同事会想要通过智能指针使用该地址,因为他听说现在就是这样做的,然后来到 Stack Overflow 并了解到他们应该使用 \xe2\x80\x9ereset\xe2 \x80\x9d 为该指针。这是错误的,错误得令人痛苦。
\n您只能分配另一个unique_ptr或nullptr. 如果你仔细想想,这也是有道理的(虽然reset会让你做你想做的事,但我认为这实际上是 中的一个错误或缺陷unique_ptr)。
Aunique_ptr是指向对象的唯一所有者。当它超出范围时,它将删除该对象。
这意味着您的函数具有接收器语义。您传入的指针(或者更确切地说是指向的对象)被消耗,也就是说,它在函数内部“消失”(下沉)。您通过引用传入一个对象(一个甚至不一定是堆分配的对象) ,如果您传入具有自动存储功能的对象,请准备好惊喜!)然后它突然消失了。砰。
应该正确传达接收器语义。您应该传递一个unique_ptras 函数参数。唯一指针无法复制,因此这将迫使该函数的用户使用std::move,从而意识到正在发生的事情。
一个对象“消失”是一个令人讨厌的惊喜,这不应该只是无意中发生的。
| 归档时间: |
|
| 查看次数: |
22229 次 |
| 最近记录: |