未封装意味着不可改变?

时间:2011-07-02 08:09:07

标签: c++ oop encapsulation public

我在 Effective C ++ 中遇到了这一行:

  

公共意味着未被封装,实际上,未封装意味着不可改变,尤其是   对于广泛使用的类。因为广泛使用的类最需要封装   他们是最能从更好地替换一个实现的能力中受益的人   一个

作者的意思是“公共意味着未被封装,实际上,未封装意味着不可改变”?

未解决的问题如何不可改变?

4 个答案:

答案 0 :(得分:7)

一般的想法很简单。如果你公开一些东西,那么有人可以并且可能会使用它。因此,如果您更改公开的内容,则使用它的所有代码都会立即中断。打破人们的代码很糟糕;它往往会导致他们不再想要使用你的代码了,因为现在你已经强迫他们重写所有的东西只是因为你想使用不同类型的东西。

公共接口是类的实现与其用户之间的契约。改变合同,特别是没有提前通知,被认为是非常粗鲁的。

如果你的所有代码都是内部的,那很好。但如果不是,如果你正在为其他人创建一个图书馆(无论是在本地还是只是出售图书馆),那么人们就不太可能对界面变化感到高兴。

这不是C ++规则的问题;这只是界面设计规则的问题。由于公共事物是界面的一部分,你必须小心你公开的东西。

答案 1 :(得分:3)

封装是指您只能通过接口方法访问类的数据成员。使用方法的效果是“隐藏”数据成员的实际实现,以便您可以更改它而无需通过接口方法更改使用该类的代码(前提是您不更改它们的方式定义的)。

另一方面,如果您不使用接口方法来隐藏数据成员实现,则需要在数据成员的任何更改之前修改使用它的所有代码。

假设您有一个包含名称列表的字符串向量的类。如果你公开该向量,那么所有其他类可以决定直接使用它,并通过它们在向量中的索引访问它包含的字符串(索引作为识别字符串的键,比如说)。

稍后,您可以决定需要一张地图来管理所有这些字符串(您的要求已更改)。您将数据成员定义更改为映射,您的代码将不再编译。这就是“几乎不可改变”的含义。

通过封装管理此方法的“正确”方法是将数据成员设为私有,并定义一个接口方法,如:

std::string getStringWithKey(int index);

此方法将在第一个实现中访问向量,并在第二个案例中访问映射。所有这些都以透明的方式:使用该方法的代码(而不是直接访问数据成员)将不需要修改,因此您可以随意更改数据成员实现,而且几乎不需要任何费用。

这是过于简单化,因为接口设计不是一件简单的事情,接口也会发生变化,但我希望它有助于澄清事情。

答案 2 :(得分:2)

我想作者会给出最好的答案。我的猜测是,他的意思是,如果你宣布一个公共成员并在你的代码中的许多其他地方使用它,那么如果你以后决定改变那个成员,那么改变所有这些地方将是一项艰苦的工作。

答案 3 :(得分:0)

他指的是数据成员,他说公开接触数据成员作为公共接口的一部分意味着你永远不能改变他们的性质,,即名称和类型。