【发布时间】:2021-07-09 16:18:46
【问题描述】:
class Resource {
Handle resource_handle;
public:
friend void swap(Resource &a, Resource &b); // swap for the partial copy/swap idiom
Resource(); // Default with uninitialized handle whose destruction is a noop
Resource(std::string location); // Construction of resource (e.g. load something from disk)
Resource(Resource &&other); // Move constructor to receive from returns of functions
Resource &operator=(Resource other); // Sawp assignment to implement copy/swap idiom
Resoruce(Resource &other) = delete; // You can not copy resources
Resource &operator=(Resource &other) = delete; // You can not copy resources
};
管理资源句柄(文件句柄、gpu 句柄、互斥体)的类希望防止资源句柄被复制,因此包装类的解构会自动释放资源一次且仅一次,没有任何东西可以不再访问句柄,因为对象的生命周期已经结束并且(希望)不再存在指向包装器的引用或指针。
5(半)的复制/交换和规则说通常你想定义一个复制构造函数/赋值运算符。复制资源句柄显然是不需要的。我是否理解正确,因此只需删除任何其他构造函数/赋值运算符就可以解决这个问题(如果我分配了未转换为右值的东西(因此在分配完成后不再存在),编译器会冲我大喊大叫))
这与这个问题有关,因为我要构造的资源实际上只有在它们所属的包含数据结构已经构造之后才能构造,因此需要移动资源,而不是复制它们。
【问题讨论】:
-
如果您明确将它们声明为
= delete,那么它们可以作为一种可能的替代方案,如果选择或不明确将导致编译错误。但是,如果您允许编译器抑制它们并且从不合成它们,那么它们根本不存在。这是一个重要的区别(有时是正确的事情,有时是错误的事情......取决于需要)。 -
注意 -
Resource &operator=(Resource other); // Sawp assignment...将换成临时的,可能不是你想做的。我还将使用swap成员函数来明确意图并删除赋值运算符。 -
您想将复制和交换与不可复制的类一起使用吗?为什么?
-
你的做法是合理的,除了operator=(Resource)。您可能还需要一个移动赋值运算符。 (Resource& operator=(Resource&& other))
标签: c++ raii copy-and-swap