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

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

本文关键字:成员 ptr unique 有一个 原始 指针 拥有 访问      更新时间:2023-10-16

我有一个类,它有一个unique_ptr成员,并且这个类保留这个对象的唯一所有权。但是,外部类可能需要访问该对象。在这种情况下,我应该返回一个原始指针吗?shared_ptr似乎不正确,因为这意味着访问类现在共享该内存的所有权,而我想说清楚的是,原始类是唯一的所有者。

例如,也许我有一个拥有根节点的树类。另一个类可能出于某种原因希望探索树,并且需要一个指向根节点的指针来完成此操作。部分实现可能像这样:

class Tree
{    
public:
    Node* GetRoot()
    {
        return m_root.Get();
    }
private:
    std::unique_ptr<Node> m_root;
};

这种做法不好吗?更好的解决方案是什么?

更正常的实现可能是Tree公开迭代器或提供visit机制来探索树,而不是公开Tree本身的实现细节。公开实现细节意味着你永远不能改变树的底层结构,而不会有破坏该代码的未知客户端的风险。

如果您绝对坚持需要这样做,那么至少将指针返回为const,例如const Node* GetRoot() const,因为外部客户端绝对不应该改变树结构。

Scott Meyers, Effective c++ Item 15说是的,尽管主要原因是为了与遗留代码的交互。如果你在一个受控的环境中——例如,一个没有多少遗留代码的初创公司,可以很容易地根据需要或在家庭作业中扩展类——可能很少需要,而且可能只会鼓励错误地使用类。但是更可重用的方法是公开原始资源。

请记住,当人们说"避免使用指针"时,他们真正的意思是"使用所有权语义",指针本身并不坏。

返回非所属指针是一种可接受的获取引用的方式,这些引用也可能为空,并且比其他替代方法更危险。现在,在您的情况下,这只有在您的树打算用作时才有意义,而不是像std::map那样在内部使用树。

这样做是不常见的,因为通常你会想要抽象掉指针和资源。