在这种特殊情况下,应该传递指针或非常数引用吗
Should a pointer or a non-const reference be passed in this particular case?
假设类:
struct SimplifiedContainer {
void add(Node *n); // the key is computed based on `n`
std::map<int, Node*> myMap;
};
问题集中在add
函数成员上,它向容器添加了一个节点。该函数采用非智能指针,因为节点由另一个容器所有。问题是:add
应该取Node&
吗?
永远不应该做的一件事是获取引用,只获取它的地址并将其存储在容器中。你不应该这样做的原因有很多。由于你不能按原样直接将引用存储在容器中(是的,你可以用std::ref将它们包装起来,它只会获取它们的指针,但它是非透明的,我看到人们不理解引擎盖下发生了什么),你的接口只剩下指针或类似指针的对象。
现在,冒着被否决的危险,我个人的建议是坚持你所拥有的。我认为那里没有问题。您有一个管理指针的实体,并且有一个指向管理容器的索引。与其让它成为shared_ptr(以及与shared_ptr管理相关的性能问题的开放代码,以及应用程序开发人员绞尽脑汁试图理解指针的生命周期),不如让它保持原样。当然,你必须确保索引始终与主容器同步,但如果你不确保这一点,您将面临比指针管理不善或悬空更大的问题。
编辑我将列出几个原因,为什么参考地址转换是不明智的。首先,operator &
可以过载并返回其他内容。虽然这是一件可怕的事情,但人们仍然会这样做——所以你的界面可能会因此而崩溃。其次,当函数接受指针时,任何一个调用它的优秀程序员都会验证指针是如何使用的(这就是为什么你应该提供注释,指示函数存储指针,但不管理它)。通过这种方式,开发人员将知道给您的函数赋予什么。但是接受引用的函数不那么可疑,所以程序员会很乐意给它任何东西,包括局部变量。一般的理解是,如果你接受了一个推荐人,你就会发现有任何推荐人。
我的建议:
该函数采用非智能指针,因为节点由另一个容器所有
这不是不使用智能指针的理由
事实上,这是使用智能指针的一个很好的理由。
如果你的"另一个容器"没有存储智能指针,它应该是(特别是std::shared_ptr
)。
在这种特殊情况下,应该传递指针还是非常数引用?
两者都没有。
接受并存储std::weak_ptr
我的回答是:
您已设置将std::unique_ptr
存储在拥有容器中,并避开非拥有容器的智能指针安全性。
因此,我建议你坚持使用指针:
- 对于对称性
- 因为您将存储指针(不能[直接]将引用存储在容器中),因此接受指针到执行该存储的例程中"感觉"是正确的,并且
- 因为它强烈地表明你正在自己实现内存管理(因为你对容器各自寿命的保证来自你的大脑/文档/希望/梦想,而不是实际的C++范围规则)
- 引用最好用作不必存在很长时间的透明别名,通常是为了方便,很少用作逻辑句柄
然而,这完全是主观的,归根结底是风格观点。
这取决于情况。如果SimplifiedContainer
拥有节点,则您应该收到一个std::unique_ptr
。要确定它是否是所有者,只需检查谁负责删除节点即可。委托人通常是所有者。
如果SimplifiedContainer
不是所有者,那么您可以在add
中接收引用并将指针插入列表中。然而,您的类对于悬空指针是不安全的。
对于这种容器,最好的模式是实现一个container_view(这正是你想要做的!),它是一个容器的非拥有视图。如果是这样的话,您可以包含一个reference_wrapper
的列表,您可以在这个页面上看到正在运行的模式
- 1d 智能指针不适用于语法 (*)++
- 在C#中处理C++指针而不使用unsafe的最佳方法
- 为什么使用 "this" 指针调用派生成员函数?
- 函数向量_指针有不同的原型,我可以构建一个吗
- 使用指针从C++中的数组中获取最大值
- 助记符和指向成员语法的指针
- 嵌入方指针压缩已禁用
- 数组的指针从不分段故障
- C++ 指针的内存地址和指向数组的内存地址如何相同?
- 何时在引用或唯一指针上使用移动语义
- QMetaObject invokeMethod的基于函数指针的语法
- 如何从 std::atomic 中提取指针 T<T>?
- 如何在 C# 中映射双 C 结构指针?
- C++将浮点指针值舍入为小数位数
- 修改指针中的值非常慢?
- C++:C字符串、指针和一个非常有趣的while循环
- 使用指针 - 非常困惑!C++
- c++ 难以理解使用智能指针的非常基本的概念
- 涉及指针成员变量和多态性的非常奇怪的问题
- 犯了一个非常愚蠢的 C/C++ 数组/数组指针错误