我想知道哪个是编写管理某些资源的类的最佳做法,如果我们明确地给予该类独特的所有权或者只是以共享所有权来执行它,那会更好吗?
独特的所有权
std::unique_ptr<Resource> resource;
Resource* resource_ptr = resource.get();
resourceManager.add(std::move(resource));
resource_ptr->doStuff();
VS
共享所有权
std::shared_ptr<Resource> resource;
resourceManager.add(resource);
resource->doStuff();
答案 0 :(得分:4)
您的代码示例并没有多大意义。无论如何,我会回答你更普遍的问题......
如果我们明确地给予该类独特的所有权或者仅使用共享所有权来做它会更好吗?
首先,问问自己:“我需要动态内存分配吗?”。很多时候你可能不需要它 - 喜欢值指针并尝试使用堆栈。
如果您确实需要动态内存分配,请问自己“谁将拥有已分配的内存/对象?”。
如果您只需要一个拥有者(非常可能),您应该这样做
使用std::unique_ptr
。这是一个零成本的抽象
new
/ delete
。 (可以指定不同的deallocator 。)
如果您需要共享所有权,则应使用std::shared_ptr
。这是不零成本抽象,因为它使用原子操作和额外的“控制块”来跟踪所有所有者。
tl; dr :更喜欢动态分配的值。除非您有充分理由使用后者,否则请unique_ptr
加shared_ptr
。
答案 1 :(得分:-1)
在您的情况下,共享所有权是有道理的:
std::unique_ptr<Resource> resource;
Resource* resource_ptr = resource.get();
resourceManager.add(std::move(resource));
resource_ptr->doStuff();
您正在将指针传递给管理器,而不是在资源管理器外部的基础对象上调用操作符...这很简单,因为您知道resource_ptr现在可能是指向垃圾的指针,因为ressourceManager销毁了unique_ptr你搬进去了。
拥有共享所有权:
std::shared_ptr<Resource> resource;
resourceManager.add(resource);
resource->doStuff();
当你调用&#34; doStuff&#34; ...时,100%保证资源仍在那里,除非你将shared_ptr强制转换为原始资源并在resourceManager中将其删除,但这将是不好的做法
人们常常会说uniq_ptr优先于share_ptr,因为使用uniq_ptr可以带来更好的设计(例如,没有RessourceManager类,但也管理它的资源:P ...)但是,一个好的经验法则是自己:
&#34;我是否需要在任何时间点从此智能指针获取原始指针?&#34;如果答案是肯定的,那么您可能使用了错误的智能指针,因为将其转换为原始指针会使智能指针所具有的所有安全防护装置无效,以帮助您编写可预测的代码。