我遇到了几个问题,其中答案表明使用T *绝不是最好的主意。
虽然我已经大量使用RIIC,但我的代码中有一个特殊点,我使用T *。阅读几个自动指针,我找不到一个我会说使用它有明显优势的地方。
我的情景:
class MyClass
{
...
// This map is huge and only used by MyClass and
// and several objects that are only used by MyClass as well.
HashMap<string, Id> _hugeIdMap;
...
void doSomething()
{
MyMapper mapper;
// Here is what I pass. The reason I can't pass a const-ref is
// that the mapper may possibly assign new IDs for keys not yet in the map.
mapper.setIdMap(&_hugeIdMap);
mapper.map(...);
}
}
MyMapper
现在有一个HashMap<...>*
成员,根据对无关问题的问题的高度投票答案 - 从来不是一个好主意(在映射器的实例之前,映射器将超出范围) {1}}确实如此,因此我不认为这是一个太大的问题。映射器中没有MyClass
,也不需要new
。
那么在这个特定用例中最好的替代方案是什么?
答案 0 :(得分:8)
我个人认为原始指针(或引用)在这里没问题。智能指针与管理指向的对象的生命周期有关,在这种情况下,MyMapper
不管理该对象的生命周期,MyClass
是。您也不应该有一个指向未动态分配的对象的智能指针(在这种情况下哈希映射不是这样)。
就个人而言,我会使用以下内容:
class MyMapper
{
public:
MyMapper(HashMap<string, Id> &map)
: _map(map)
{
}
private:
HashMap<string, Id> &_map
};
请注意,这将阻止MyMapper
拥有赋值运算符,并且只有在构造函数中传递HashMap可以接受它才能工作;如果这是一个问题,我会使该成员成为一个指针(虽然我仍然将该参数作为参考传递,并在初始化列表中执行_map(&map)
)。
如果MyMapper
或使用哈希映射的任何其他类可能比MyClass
更长,那么你必须开始考虑智能指针。在这种情况下,我可能会推荐std::shared_ptr
,但您必须在任何地方使用它:_hugeIdMap
必须是shared_ptr
到动态分配的值,而不是常规非指针字段。
<强>更新强>
由于您说由于项目的编码标准,使用引用是不可接受的,我建议只是坚持使用原始指针,原因如上所述。
答案 1 :(得分:1)
当对象没有责任删除对象时,裸指针(通常称为原始指针)就可以了。在MyMapper的情况下,指针指向MyClass已经拥有的对象,因此绝对没有删除它。当您打算通过它们删除对象时使用原始指针时会出现问题,这就是问题所在。人们只有在遇到问题时才会提出问题,这就是为什么你几乎总是看到它只用在有问题的环境中,但是非拥有环境中的原始指针很好。
答案 2 :(得分:0)
如何将它传递给构造函数并保持引用(或const-reference)呢?这样就明确了你不拥有这个对象的意图。
传递自动指针或共享指针主要用于通信所有权。
关于您的编码风格:
我们的编码标准有一个惯例,即永远不会传递非常量引用。
无论您使用C ++引用机制还是C ++指针机制,您都会将(英语意思)引用传递给将要更改的内部存储。我认为你的编码标准试图告诉你根本不要这样做,不是说你不能使用引用这样做,而是你可以用另一种方式来做。