C++有一个像unique_ptr这样的智能指针,带有"构造前的破坏"语义吗?

Wae*_*elJ 1 c++ smart-pointers resource-management resourcemanager unique-ptr

问题

考虑这个简单的类:

struct C {
   C(const char* name) : name(name) {
         cout << "constructing " << name  << endl;
   }

   ~C() {
       cout << "destructing " << name << endl;
   }

   string name;
};
Run Code Online (Sandbox Code Playgroud)

我想有一个指向这个类的实例的指针,它通常被另一个实例替换.但是,我希望创建新实例之前销毁当前实例.

错误的例子

如果我unique_ptr以正常方式使用a ,这不起作用:

unique_ptr<C> c( new C("the first one"));
c.reset(new C("the second one"));
Run Code Online (Sandbox Code Playgroud)

(不受欢迎的)输出:

构建第一个

构建第二个

破坏第一个

破坏第二个

丑陋的例子

可以如下实现期望的效果:

unique_ptr<C> c( new C("the first one"));
c.reset();  // explicitly destruct the first one first
c.reset(new C("the second one"));
Run Code Online (Sandbox Code Playgroud)

输出:

构建第一个

破坏第一个

构建第二个

破坏第二个

试图解决方案

这是我尝试使用此行为创建智能指针.这样的智能指针是否已存在?

template<typename Resource>
class ResourceManager {
  public:
    ResourceManager() {}

    template<typename... Arguments>
    ResourceManager(Arguments&&... args) {
      replace<Arguments...>(std::forward<Arguments>(args)...);
    }

    template<typename... Arguments>    
    void replace(Arguments&&... args) {
      resource.reset();
      resource.reset(new Resource(std::forward<Arguments>(args)...));
    }

  private:
    unique_ptr<Resource> resource;
};

template<typename Resource, typename... Arguments>
ResourceManager<Resource> make_resource_manager(Arguments... args) {
        return ResourceManager<Resource>(args...);
}

int main() {
   //ResourceManager<C, const char*> r("first1");
   auto r = make_resource_manager<C>("first1");
   r.replace("second1");
}
Run Code Online (Sandbox Code Playgroud)

输出:

构建第一个

破坏第一个

构建第二个

破坏第二个

编辑:将'Arguments ...'模板移动到功能级别.

编辑2:现在正确转发'参数'.

Ded*_*tor 5

在C++中尽可能避免在构造新状态之前销毁旧状态,因为无法提供强大的异常保证方式:"操作成功,或者抛出异常而不改变任何东西 ".因此,标准库没有这样的(我甚至不能命名添加它的框架).

天真和错误的复制构造函数有时会这样做.
如果你故意想要获得这种行为,那么没有比为自己编写代码更好的了.
但是,要确定这是你想要的,并为后代记录.

ResourceManager似乎主要做你想做的事.
尽管如此,请确保方法名称/类名明确地调出您的非标准行为(既不是ResourceManagerreplace不够具体).