3

用使用引用的设置器隐藏指针成员是一件好事吗?

class Foo
{
    Bar* m_ptr;
public :
    void setBar(Bar& bar){m_ptr = &bar;}
};

还是最好在设置器中公开引用对象的真实类型(以及为什么)?

void setBar(Bar* bar){m_ptr = bar;}

事实上,我使用的是非“引用友好”的 stl 竞争者,因此我将指针向量作为类成员,但我更喜欢处理采用引用的方法。这样做是件坏事吗?

编辑 :

存储的成员是指针,这个例子更适合我的问题:

class Foo
{
   std::vector<FooObserver *> m_observers; 
public :

你喜欢这个:

void addObserver(FooObserver* obs);

或这个 :

void addObserver(FooObserver& obs);

?

在这两种情况下,指针都不应该为 NULL,我认为这是调用者对象的责任。

4

4 回答 4

5

对我来说,它归结为类型的语义。如果指针掩盖了一个从未打算成为的成员,NULL那么绝对在输入和输出位置都使用引用。如果值可以合法NULL,那么使用指针是最好的方法

于 2013-04-18T17:03:27.237 回答
3

这取决于您要实现的目标,两者都是完全合理的。

唯一的区别* 是void setBar(Bar* bar)它将接受空指针,而void setBar(Bar& bar)显然不会。

您可以根据是否允许空指针来选择要使用哪一个。

(*)假设作者Bar没有提供自定义operator&(无论如何这是一个糟糕的想法)。


编辑:由于您不想允许存储空指针,因此最好使用引用。您说“指针永远不应该为 NULL,我认为这是调用者对象的责任”,但是通过引用,您有机会在编译时强制执行它并避免完全依赖调用者的善意,这是更好的设计。

于 2013-04-18T17:04:12.990 回答
2

是的。由于它混淆了您对这两个对象的终生控制,请考虑这一点

void AdjustFoo(Foo& f)
{

     Bar B;
     f.setBar(B);
     //Crap f now contains a bad pointer to B after this function exists 
}

如果 foo 需要拥有一个 B,它应该拥有一个 shared_ptr 或 B 的副本。

于 2013-04-18T17:04:08.603 回答
1

这是一个约定的问题,但我更喜欢包含以下内容的内容:

  • 如果被调用的方法保留了传递对象的指针,请使用指针参数并在 API 文档中明确说明生命周期要求
  • 如果被调用的方法只是在方法执行期间偷看(并且可能戳入)传递的对象,请使用引用。
  • 接受参考说:我只接受有效的对象。
  • 接受指针表示:除非另有明确说明,否则我也接受空指针。

顺便说一句,我不喜欢到处放置共享指针。终生失去控制,所有权变得模糊。当然,共享指针仍然有非常有效的用途,但永远不要仅仅因为您不想考虑生命周期和所有权而使用它们。

于 2013-04-18T19:37:40.653 回答