公共类成员之间有什么区别
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;
};
哪一个更好?
答案 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之后,我绝对投票给你的第二个例子:私人成员,公共访问方法。