隐藏带有引用的指针

Hiding pointers with references

本文关键字:指针 引用 隐藏      更新时间:2023-10-16

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

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

还是最好在setter中公开被引用对象的真实类型(为什么)?

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

事实上,我使用的仍然是不"引用友好"的竞争者,所以我有指针的向量作为类成员,但我更喜欢处理接受引用的方法。这样做是件坏事吗?

编辑:

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

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

你喜欢这个吗?

void addObserver(FooObserver* obs);

或者:

void addObserver(FooObserver& obs);

?

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

对我来说,这归结为类型的语义。如果指针正在屏蔽一个不打算为NULL的成员,那么绝对在输入和输出位置都使用引用。如果该值可以合法地为NULL,那么使用指针是最好的方法

这取决于你想要达到什么效果,两者都是完全合理的。

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

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

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


Edit:由于您不希望允许存储空指针,因此首选引用。你说"指针永远不应该是NULL,我认为这是调用者对象的责任",但是有了引用,你就有机会在编译时强制执行,并避免完全依赖调用者的善意,这是更好的设计。

是。由于它混淆了对两个对象的生命周期控制,请考虑如下

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

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

这是惯例问题,但我更喜欢包含以下内容的

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

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