使用 unique_ptr 的方法安全吗?

问题描述 投票:0回答:2

我有一些管理 unique_ptrs 队列的代码。在其主循环中,它从队列中弹出一个条目,对其执行某些操作,然后允许该元素超出范围并被删除。到目前为止,没有问题。

我想添加一个功能,我们可以将其移动到其他地方,而不是必须删除该元素。问题是只有元素本身知道是否执行此操作或需要去哪里。

主循环类似于:

   std::deque< std::unique_ptr<Object> > queue;

   while( !queue.empty() ) {
      auto element = std::move( queue.front() );
      queue.pop_front();

      element->do_something();

      element->recycle( std::move(element) );  // ?
   }

如果回收不是对象的方法,这将不是问题,但因为它是对象的方法,我不确定它应该是什么样子。通过上面的代码,我会得到类似的东西:

class Object {
public:

   virtual void do_something();
   
   virtual void recycle( std::unique_ptr<Object> unique_this ) {
     // move unique_this somewhere, or don't and allow it to be deleted
   }
};

这样安全吗?如果recycle不移动unique_this,它将在它自己的方法之一中删除它(不过在方法的末尾)。有问题吗?

我想到避免删除这一点的一种可能性是让回收利用左值引用获取 unique_ptr,我意识到这有点奇怪。这个想法是,如果它愿意,它会将其移动到某个地方,但如果不这样做,则直到回收返回后该对象才会被删除。不过,它不一定避免在其方法之一中可能删除对象的问题,因为我们必须确保将其移动到的任何位置都不会立即删除它。

如果这样做不安全,后备计划是让 Object 返回一个回收器(即,一个不是执行回收的 Object 方法的可调用对象)。我认为这应该是可能的,但是考虑到不同的对象想要使用不同的回收器,管理回收器的类型和生命周期会有点混乱。

在我看来,第一个想法(按值传递 unqiue_ptr)是最好的,除非它违反任何规则。这样安全吗?有更好的方法吗?

c++ unique-ptr
2个回答
0
投票

这样安全吗?

是的。

如果recycle不移动unique_this,它将在它自己的方法之一中删除this(不过在方法的末尾)。有问题吗?

没有。

对象甚至可以在其自己的成员函数中

delete this;


0
投票

element->recycle(std::move(element));
在C++17之前是有问题的:
element->
可能会在移动构造函数之后求值,因此是
nullptr
。太不安全了。

自 C++17 起,求值顺序 (13) 指定在求值参数之前先求值

element->
;所以很安全。

© www.soinside.com 2019 - 2024. All rights reserved.