Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 未封装意味着不可更改?_C++_Oop_Encapsulation_Public - Fatal编程技术网

C++ 未封装意味着不可更改?

C++ 未封装意味着不可更改?,c++,oop,encapsulation,public,C++,Oop,Encapsulation,Public,我在高效的C++中遇到了这一行: 公开意味着未封装,实际上,未封装意味着不可更改,尤其是 对于广泛使用的类。但是广泛使用的类最需要封装,因为 他们是最能从用更好的实现替换一个实现的能力中获益的人 一个 作者所说的“公开意味着未封装,实际上,未封装意味着不可更改”是什么意思 那么“未封装”是如何不可更改的呢?他指的是数据成员,他说,将数据成员作为公共接口的一部分公开,意味着您永远无法更改其性质,即名称和类型。我想作者会给出最好的答案。我的猜测是,他的意思是,如果您声明一个公共成员并在代码中的许多其

我在高效的C++中遇到了这一行:

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

作者所说的“公开意味着未封装,实际上,未封装意味着不可更改”是什么意思


那么“未封装”是如何不可更改的呢?

他指的是数据成员,他说,将数据成员作为公共接口的一部分公开,意味着您永远无法更改其性质,即名称和类型。

我想作者会给出最好的答案。我的猜测是,他的意思是,如果您声明一个公共成员并在代码中的许多其他位置使用它,那么如果您以后决定更改该成员,那么更改所有这些位置将是一项艰巨的工作。

总体思路很简单。如果你把一些东西公之于众,那么有人可以而且可能会使用它。因此,如果您更改了某个公共内容,则使用它的所有代码都会立即中断。破坏人们的密码是不好的;这往往会导致他们不想再使用你的代码,因为现在你强迫他们重写他们所有的东西,只是因为你想使用不同的类型或其他东西

公共接口是类的实现和它的用户之间的契约。更改合同,特别是在没有事先通知的情况下,被认为是非常粗鲁的

如果所有代码都是内部代码,那就好了。但如果不是这样,如果你正在制作一个供其他人使用的库(无论是本地的还是仅仅出售一个库),那么人们就不太可能对界面更改感到高兴


这不是C++规则的问题;这只是界面设计规则的问题。由于公共内容是接口的一部分,因此必须注意公开的内容。

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

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

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

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

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

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


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

我永远不能更改声明为公共的数据成员的名称和类型吗!不,不,不是“常量”,而是“发布界面后不能更改设计”,因为您的用户已经开始使用公共成员。@Kerrek SB为什么在发布与公共成员的界面后不能更改设计?@Suhail,因为客户端代码将使用,你发表的东西。如果你开始改变你的公共接口,客户必须适应他们的代码。@ JuangopANZA,当我有适当的选择的公共成员时,我会得到什么好处?@ Martinho Fernandes有什么特定的理由删除java标签?GUPTA:因为这本书是专门谈论C++的。我可以删除问题中的第一行。@Suhail:是的,这是一个普通的OOP问题。这就是为什么它不应该有Java标记。或者C++标签。因为它与任何特定的语言无关;一般来说,它是关于封装的……有什么需要改变的呢?@Suhail:想法是永远不需要改变。这就是为什么你必须仔细选择你要公开的内容。如果你做得对,你将有权在不改变界面的情况下改变实现细节。@Nicol Bolas你的陈述“想法是永远不需要改变”。如果我公开我的所有成员,你会失败吗?@Suhail:因为我们假设你从事的是软件开发,你需要改变实现。其中一些成员不需要公开,因为它们依赖于实现。如果你能写一次而不必碰它,那就太好了。但是,您是想抓住永远不必触及实现的机会,还是想实际使用封装和数据隐藏技术,在不影响接口的情况下,使不可避免的实现更改成为可能?@Suhail:您将如何做到这一点?如果重构包括删除公共数据成员,那么您就是在更改接口。这意味着你正在破坏别人的密码。这正是重构不应该做的。