protected与public真的不同吗?

在一开始接触C++的class时就接触到了三种访问权限,private、protected、public。对于它们的不同C++ Primer中如此描述:在public部分定义的成员可被使用该类型的所有代码访问;在private部分定义的成员可被其他(本)类成员访问;protected成员可以被派生类对象访问但不能被该类型的普通用户访问,可以认为protected访问是private与public的混合。补充一下,protected部分定义的成员 可被其他(本)类成员访问。

一眼看上去不少人会认为,protected与private很像,因为它们定义的成员都不能被普通用户访问,都可被其他(本)类成员访问。也有不少人认为既然protected与private的成员都不能被普通用户访问,那么在设计类的时候,就把很多本应是private的成员放在了protected里,还认为若以后以此类为父类继承时还有利于在为子类提供便利,并为自己的好主意高兴。

但是事实果真如此吗?其实protected与public更像,而不是private。

为了说明这个问题,我先引入一个概念:代码破坏量,成员变量的内容改变时所破坏的代码数量,所谓改变,即是从class中移除它。

好了,以下进入我们的正题。从第一段的说明可以看出,protected是为继承而设计的,如果你设计一个类而保证它不会作为一个基类被继承,那么用protected与用private没有区别,也天下太平。但是实际却不是这样。

先来看看C++编程规范里面的说法:
保护数据具有公有数据的所有缺点,因为拥有保护数据仍然意味着抽象将与代码的无限集合共同承担维持一个或者更多不变式的职责,只不过这里的集合是由当前的派生类和未来的派生类组成的。而且,通过一个派生类,并用它来获取数据,任何代码都能够像公用数据那样容易地读取和修改保护数据。

再来看看Effective C++中的说法:
public意味着不封装,而几乎可以说,不封装意味不可改变,特别是对被广泛使用的classes而言。

protected成员变量的论点与public十分类似。实际上它和public成员变量的论点相同。对于封装性,protected成员变量的封装性是不是高过public成员变量?答案让人惊讶:并非如此。

假设我们有一个public成员变量,而我们最终取消了它。多少代码可能会被破坏呢?所有使用它的客户码都会被破坏,而那是一个不可知的大量。因为public成员变量没有封装性。假设我们有一个protected成员变量,而我们最终取消了它,有多少代码被破坏?所有使用它的derived class都会被破坏,那往往也是个不可知的大量。因此,protected成员就像public成员一样缺乏封装性,因为在这两种情况下,如果成员变量被改变,都会有不可预知的大量代码被破坏。

从封装的角度看,其实只有两种访问权限:private(封装)和其他(不封装)

从以上所述,可以看到一个有违我们一开始认识的结论,在封装性中,protected与public同等。但是每样事物都有它存在的理由,protected与public始终有着一些差别,例如:它至少让它的影响范围收缩了,派生类也只能通过派生类对象访问其基类的protected成员,派生类对其基类类型对象的protected成员没有特殊访问权限。通常不希望被普通类用户访问而且希望在其派生类中出现并使用的成员就可声明为protected,如果只是不希望被普通类用户访问或不知放在那里比较合适时,本人建议先放在private中比较好。也就是说成员被声明为protected是为了不被普通类用户访问并被继承,两者缺一不可。

你可能感兴趣的:(C/C++)