假设班级:
struct SimplifiedContainer {
void add(Node *n); // the key is computed based on `n`
std::map<int, Node*> myMap;
};
问题集中在add
函数成员,该成员向容器添加节点。该函数采用非智能指针,因为节点由另一个容器拥有。问题是:add
应该采用Node&
吗?
答案 0 :(得分:2)
该函数采用非智能指针,因为节点由另一个容器
拥有
这不是不使用智能指针的原因 事实上,使用智能指针确实 。
如果你的另一个容器&#34;不存储智能指针,它应该是(具体地,std::shared_ptr
)。
在这种特殊情况下是否应该传递指针或非const引用?
都不是。
接受并存储std::weak_ptr
。
您可以将std::unique_ptr
存储在拥有容器中,并避开非拥有容器的智能指针安全性。
因此我建议你坚持使用指针:
然而,这完全是主观的,并且归结为文体观点。
答案 1 :(得分:2)
你永远不应该做的一件事是获取一个引用只是取它的地址并将其存储在容器中。你不应该这样做的原因有很多。并且因为你不能直接在容器中存储引用(是的,你可以将它们包装在std :: ref中,它只会占用它们的指针,但它会非透明地执行,而且我看到人们不理解正在发生的事情在引擎盖下)你的界面上留有指针或类似指针的物体。
现在,冒着可怕的命中注意事项,我个人的建议是坚持你所拥有的。我觉得那里没问题。您有一个管理指针的实体,并且您拥有管理容器的索引。而不是将它变成一个shared_ptr(以及与shared_ptr管理相关的性能问题的开放代码,以及应用程序开发人员试图理解指针的生命周期),让它保持原样。当然,你必须确保索引始终与主容器同步 - 但是如果你不确定这一点,你将遇到比指针管理不善或悬空更大的问题。
修改强>
我将列出为什么做参考地址转换是不明智的几个原因。首先,operator &
可以重载并返回其他内容。虽然这是一件非常糟糕的事情,人们仍然会这样做 - 所以你的界面可能会因此而破坏。其次,当函数接受一个指针时,任何正在调用它的程序员都会验证指针的使用方式(这就是为什么你应该提供注释,指示函数存储指针,但不管理它)。这样开发人员就会知道如何赋予你的功能。但接受引用的函数不那么可疑,因此程序员很乐意给它任何东西,包括局部变量。一般的理解是,如果您接受参考,您可以找到任何参考。
答案 2 :(得分:0)
这取决于。如果SimplifiedContainer
拥有节点,则应收到std::unique_ptr
。要确定自己是否是所有者,只需检查谁负责删除该节点。删除者通常是所有者。
如果SimplifiedContainer
不是所有者,那么您可以在add
中接收引用并将指针插入列表中。但是,你的班级对于悬挂指针是不安全的。
这种容器的最佳模式是实现一个container_view(这是你正在尝试做的!),这是一个容器的非拥有视图。如果是这种情况,您可以包含reference_wrapper
的列表,您可以在此page