当我不知道如何分配 `ptr` 时,`std::unique_ptr<Base>(ptr)` 的销毁策略?

Destruction policy for `std::unique_ptr<Base>(ptr)` when I don't know how `ptr` was allocated?

另一个 "modern C++" 初学者问题。我似乎对如何正确使用智能指针/智能指针销毁策略有一些误解。

struct Base {
    virtual Base* clone() const = 0;
    virtual ~Base() { }
};

void clone_and_use(const Base &original) {
    auto clone = std::unique_ptr<Base>(original.clone());
    …  // do something with `clone`
}

据我所知,当 clone 超出范围时,由于 std::default_delete<Base> 使用的销毁策略,指向的内存将是 deleted 17=](这似乎等同于 std::unique_ptr<Base, std::default_delete<Base>>)。

如果 original.clone() 返回一个指向 不是 分配给 new 的内存的指针怎么办?显然,标准的 std::default_delete<Base> 销毁策略是不合适的——delete 只能与 new 一起使用,但不能与 new[]malloc 或其他任何东西一起使用——我应该在创建 clone 智能指针时指定一个不同的销毁策略……但我会指定哪个?

    auto clone = std::unique_ptr<Base, ?>(original.clone());
    //                                 ^

我猜我必须扩展 Base 这样我就可以简单地要求任何派生类型提供适合其 clone() 实现的销毁策略,但我不确定我会怎么做。

谁能告诉我怎么做:

你的clone()应该return一个合适的智能指针,即

virtual std::unique_ptr<Base> clone() {
...
}

这样就避免了歧义。

只需要 Base 定义一个 clone 方法,returns 具有正确删除器的智能指针。

void clone_and_use(const Base& original) {
  auto clone = original.Clone();
  ... // do something with `clone`
}

std::unique_ptr<Base, BaseDeleter> Clone() const {
    return std::unique_ptr<Base, BaseDeleter>(new Base(this));
}

或者,您可以为您的类型覆盖 std::default_delete

namespace std
{
   template<>
   class default_delete<Base>
   {
   public:
      void operator()(Base* ptr)
      {
         // Do delete operation on `ptr`
      }
   };
 }

What if original.clone() returned a pointer to memory that was not allocated with new?

如果您不知道如何解除分配它,则无论有无任何智能指针的帮助,您都无法解除分配它class。因此,您不能以任何形式取得它的所有权。

How to properly work with smart pointer destruction policies

您不能使用未知策略。如何在 your class 中正确使用智能指针销毁策略?简单:它是 你的 class。让政策为人所知。决定一项政策并记录您的决定,因此编写派生 class 的每个人都必须遵守。或者,将输出参数 std::function& deletePolicy 添加到 clone,然后将 clone 包装在 returns 和 unique_ptr.

的便利函数中