使用哪种(自动)指针?

时间:2011-07-20 12:19:14

标签: c++ pointers auto-ptr

我遇到了几个问题,其中答案表明使用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

那么在这个特定用例中最好的替代方案是什么?

3 个答案:

答案 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 ++指针机制,您都会将(英语意思)引用传递给将要更改的内部存储。我认为你的编码标准试图告诉你根本不要这样做,不是说你不能使用引用这样做,而是你可以用另一种方式来做。