拥有一个具有原始指针访问器的unique_ptr成员是不好的做法吗?
Is it bad practice to have a unique_ptr member that has a raw pointer accessor?
我有一个类,它有一个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
那样在内部使用树。
这样做是不常见的,因为通常你会想要抽象掉指针和资源。
- 将成员变量添加到共享库中的类中,不会破坏二进制兼容性吗
- 对RValue对象调用的LValue ref限定成员函数
- 为什么使用 "this" 指针调用派生成员函数?
- 具有奇怪重复模板模式的派生类中的成员变量已损坏
- 助记符和指向成员语法的指针
- 用于访问容器<T>数据成员的正确 API
- 内置函数可查看CPP中的成员变量
- 是否可以初始化不可复制类型的成员变量(或基类)
- 如果C++类在类方法中具有动态分配,但没有构造函数/析构函数或任何非静态成员,那么它仍然是POD类型吗
- 找不到成员对象:没有名为get_event()的成员,也处理多态性和向量
- 嵌套在类中时无法设置成员数据
- 为什么在没有显式默认构造函数的情况下,将另一个结构封装在联合中作为成员的结构不能编译
- 将函数类成员映射到类本身内部
- 初始pointCloudt :: PTR类成员
- 通过成员函数将唯一 ptr 的向量附加到另一个向量
- LNK 2001 未解析的外部在 NPPluginFuncs 结构 ptr 作为静态类成员
- 我应该通过引用、值或ptr来存储一个完全封装的成员吗
- 从虚拟成员函数ptr中进行类型推导(bug?)
- 一个唯一的ptr类如何将它的实例指针传递给它的成员对象
- ptr到成员模板参数的友元语法