返回对私有成员的引用的公共类成员或方法?

时间:2012-07-04 17:08:46

标签: c++

公共类成员之间有什么区别

class data
{
public:

    std::list<data> list_of_data;
};

一个返回私有成员作为参考的方法?

class data
{
public:

   std::list<data>& get_data()
   { return list_of_data; }

private:

    std::list<data> list_of_data;
};

哪一个更好?

5 个答案:

答案 0 :(得分:3)

这个问题没有多大意义。如果你公开广播这样的事实:在第二种情况下,list_of_data确实是data的成员(即使它是私有的),那么实际上没有区别。

但这不是我们私人会员的意思。在典型的C ++设计中,在第二个变体中,外部代码不允许使用有关data的私有成员的任何知识。外部代码唯一知道的是公共get_data()成员。 get_data()代表实际数据的地方 - 外人不知道也不关心。

在这种情况下,差异变得非常明显。

  • 在第一种情况下,您揭露list_of_data实际上是作为班级data的成员出现的事实。例如,它立即意味着list_of_data的生命周期与相应的data实例的生命周期相同。这也意味着不同的data个实例拥有不同的list_of_data成员。

  • 在第二种情况下,你不会暴露任何类似的东西。外部代码不知道实际std::list<data>对象的位置以及它的生命周期。外部代码不知道data的不同实例是否会返回其get_data()成员的不同引用。为了获得这些问题的答案,外部用户必须注意代码的预期设计,而不是通过阅读代码来得出结论。这是一件好事。

这就是我们经常使用访问器函数(甚至是引用返回函数)而不是公开公开数据成员的全部原因。

答案 1 :(得分:2)

第二种方法几乎总是更令人满意。它增加了一些额外的抽象,足以使它非常有用。

例如,使用第二种方法,您可以将成员变量移动到类中的任何其他复合,并仍然维护接口。您甚至可以将其移至PIMPL并删除要求以包含<list>。或者您可以将该功能设为虚拟并将该成员移动到其他位置。它使得基本上所有使用你的类的代码都更能抵抗变化,这总是好的。

在最基本的形式中,函数通常甚至内联,在运行时使抽象自由。

现在唯一没有真正免费的方面是程序员时间,如果你认为省略编写函数更具成本效益,那就这样吧。但是你应该使用其中一种“哑”聚合类型,例如tuple<>pair<>

答案 2 :(得分:0)

如果它不是结构(即只有没有任何逻辑的数据) - 成员必须是私有的。 有关解释,请阅读Herb Sutter。

答案 3 :(得分:0)

这两种方法都是错误的封装,因为它们可以修改对象,甚至可以用新对象替换它。相反,使用按值返回对象的get方法或const引用:

const MyClass &getObj() { .... }

以便无法修改返回的对象。

修改 的 如果您仍想修改返回的对象,则只需通过引用返回它。在我看来,这至少比public field好。

答案 4 :(得分:0)

让我向您介绍几篇文章:

gotw #70 - encapsulation处理有关数据成员是公开的,受保护的,私有的问题。

gotw #76: uses and abuses of access rights

在阅读了包含几篇新文章(包括上述文章)的Herb Sutter Exceptional C++ style之后,我绝对投票给你的第二个例子:私人成员,公共访问方法。