6

我遇到了几个问题,其中的答案表明使用 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<...>*成员,根据对无关问题的高度投票回答,这绝不是一个好主意(尽管映射器会在实例之前超出范围MyClass,因此我不认为这是一个太大的问题。new映射器中没有,也不需要delete)。

那么在这个特定用例中最好的选择是什么?

4

3 回答 3

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动态分配的值,而不是常规的非指针字段。


更新:

既然您说由于项目的编码标准,使用引用是不可接受的,我建议出于上述原因坚持使用原始指针。

于 2011-07-20T12:27:57.277 回答
1

当对象不负责删除对象时,裸指针(通常称为原始指针)就可以了。在 MyMapper 的情况下,指针指向 MyClass 已经拥有的对象,因此绝对可以不删除它。当您确实打算通过它们删除对象时使用原始指针时会出现问题,这就是问题所在。人们只有在遇到问题时才会提出问题,这就是为什么您几乎总是看到它仅在有问题的上下文中使用,但在非拥有上下文中的原始指针很好。

于 2011-07-20T12:40:33.717 回答
0

将它传递给构造函数并保持对它的引用(或常量引用)怎么样?这样,您不拥有该对象的意图就很明确了。

传递自动指针或共享指针主要用于传达所有权。

  • 共享指针表示它是共享的
  • 自动指针表明这是接收者的责任
  • 参考表明这是发件人的责任
  • 空白指针不表示任何内容。

关于您的编码风格:

我们的编码标准有一个约定,即永远不要传递非常量引用。

无论您使用 C++ 引用机制还是 C++ 指针机制,您都在传递一个(英文意思)对将更改的内部存储的引用。我认为您的编码标准试图告诉您根本不要这样做,并不是说您不能使用引用来这样做,而是您可以用另一种方式来做。

于 2011-07-20T12:46:38.723 回答