简体   繁体   English

拥有一个带有原始指针访问器的unique_ptr成员是不好的做法吗?

[英]Is it bad practice to have a unique_ptr member that has a raw pointer accessor?

I have a class that has a unique_ptr member, and this class retains sole ownership of this object. 我有一个具有unique_ptr成员的类,并且该类保留对该对象的唯一所有权。 However, external classes may require access to this object. 但是,外部类可能需要访问此对象。 In this case, should I just return a raw pointer? 在这种情况下,我应该只返回原始指针吗? shared_ptr doesn't seem to be correct because that would imply that the accessing class now shares ownership of that memory, whereas I want to make it clear that the original class is the sole owner. shared_ptr似乎是不正确的,因为这意味着访问类现在共享该内存的所有权,而我想弄清楚原始类是唯一的所有者。

For example, perhaps I have a tree class that owns a root node. 例如,也许我有一个拥有根节点的树类。 Another class may wish to explore the tree for some reason, and requires a pointer to the root node to do this. 另一个类可能出于某种原因希望浏览树,并且需要指向根节点的指针来执行此操作。 A partial implementation might look like: 部分实现可能看起来像:

class Tree
{    
public:
    Node* GetRoot()
    {
        return m_root.Get();
    }

private:
    std::unique_ptr<Node> m_root;
};

Is this bad practice? 这是不好的做法吗? What would a better solution be? 有什么更好的解决方案?

A more normal implementation might be for the Tree to expose iterators or provide a visit mechanism to explore the tree, rather than exposing the implementation details of the Tree itself. 一个更普通的实现可能是让Tree公开迭代器或提供visit机制来浏览树,而不是公开Tree本身的实现细节。 Exposing the implementation details means that you can never change the tree's underlying structure without risk of breaking who-knows-how-many clients of that code. 公开实现细节意味着您永远都无法更改树的底层结构,而又不会破坏该代码的“谁知道多少”客户端。

If you absolutely insist there's a need for this, at least return the pointer as const , such as const Node* GetRoot() const because external clients should absolutely not be mutating the tree structure. 如果您绝对需const Node* GetRoot() const ,则至少将指针返回为const ,例如const Node* GetRoot() const因为外部客户端绝对不应使树结构发生变化。

Scott Meyers, Effective C++ Item 15 says yes, although the primary reason is for interactivity with legacy code. Scott Meyers, Effective C ++ Item 15说是,尽管主要原因是与遗留代码的交互。 If you are in a controlled environment - eg a startup where there is little legacy code and it's easy to extend a class as needed or in a homework assignment - there may be little need and it may only encourage using the class incorrectly. 如果您处于受控环境中(例如,遗留代码很少且很容易根据需要扩展课程或在家庭作业中进行扩展的初创企业),则可能几乎没有需求,并且可能只会鼓励错误地使用该课程。 But the more reusable approach is to expose raw resources. 但是,更可重用的方法是公开原始资源。

Keep in mind that when people say "avoid pointers" they really mean "use ownership semantics", and that pointers are not inherently bad. 请记住,当人们说“避免指针”时,它们的实际含义是“使用所有权语义”,并且指针并不是天生就不好的。

Returning a non-owning pointer is an acceptable way of getting references that may also be null and isn't anymore dangerous than the alternatives. 返回非拥有的指针是获取引用的一种可接受方法,该引用也可能为null,并且比其他方法不再危险。 Now, in your case this would only make sense if your tree was meant to be used as a tree , rather than using a tree internally such as std::map does. 现在,在您的情况下,这仅在将树用作而不是在内部像std::map这样使用树时才有意义。

It's uncommon to do this though as usually you'll want the pointers and resources abstracted away. 尽管通常需要将指针和资源抽象化,但这并不常见。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM