我是荔园微风,作为一名在IT界整整25年的老兵,今天来说说Visual C++中类的继承及类中成员的访问特性,也就是来搞懂public、protected、private这三个东西。
很多人搞不清楚这三个东西,并且很容易弄错,其实不是学习的人的错,而是网上很多帖子要不就是太复杂把初学者搞晕,要不就是只说了public、protected、private这三个东西的第一层意思,没有说第二层意思导致初学者搞错了意思。
现在我们就来好好说说public、protected、private这三个东西。
我们先来看public、protected、private的第一层意思。
(一)public、protected、private三种访问权限的比较
1. public定义的成员可以在任何地方被访问。
2. protected定义的成员只能在该类及其子类中访问。
3. private定义的成员只能在该类自身中访问。
上面这个第一层意思,是指被public、protected、private这三个东西修饰的成员到底具有什么被别的类访问的权限。我打一个什么比方比较好呢。来看看。
被public定义的成员就好比某一户人家的客厅,可以欢迎客人到你家来访问。可以在这里请客人吃饭、看电视、交谈等等。也就是说,类以外的程序想访问类里面的成员,他只能访问public定义的成员,所以public都是公开的。
被protected定义的成员就好比某一户人家的书房。这个区域客人一般不让他们进,往往是只给小孩使用的,也就是给子类访问的,当然家长也可以用,所以本类成员也可以访问protected定义的成员。
被private定义的成员就好比某一户人家的卧室,这个区域绝对不给访客访问,一般也不让小孩访问,小孩有自己的房间,这个房间只给家长访问。哈哈哈,我这个比喻不错吧。
好,我们再先来看public、protected、private的第二层意思。这一层意思和上面的第一层意思在用法上完全不同,这就是大家最容易搞错的地方。或者我可以这么说,下面的 public、protected、 private和上面的 public、protected、private是不一样的,我们可以当做全新的 public、protected或 private来看待,我们把下面的public、protected或 private当成全新的来看,就不会和上面的public、protected或 private搞混。
(二)public、protected、private在继承关系方面的比较
对于继承,也可以有 public、protected或 private 这三种访问权限去继承基类中的成员。
例如,如下所示代码中,
class Fish : public Animal
Fish类继承Animal类,就是采用 public的继承方式。
1. 如果在定义派生类时没有指定如何继承访问权限,则默认为private。
2. 如果派生类以private访问权限继承基类,则基类中的成员在派生类中都变成了private类型的访问权限。
3. 如果派生类以public访问权限继承基类,则基类中的成员在派生类中仍以原来的访问权限在派生类中出现。
4. 如果派生类以protected访问权限承基类,则基类中的public和protected成员在派生类中都变成了protected类型的访问权限。
5. 基类中的private成员不能被派生类访问,因此,private成员不能被派生类所继承。
上面的内容主要是给急性子看,下面我们来慢慢总结一下。
数据隐藏是C++面向对象编程的重要特征之一,它允许我们隐藏对象内部细节即数据成员,防止程序的函数直接访问一个类对象的内部表示、数据成员和成员函数。对类成员函数的访问限制由访问修饰符指定。访问修饰符在 C++ 中也称为可见性模式,private、public 和 protected 都是可见性模式的类型。
对比与总结
C++ 中 Private、Public 和 Protected 的区别
Private | Public | Protected |
声明为private类成员只能由基类内部的函数访问。 | 可以从任何地方访问声明为public的类成员。 | 声明为protected类成员可以在基类及其派生类中访问。 |
private成员使用关键字private后跟冒号 (:) 字符来声明。 | public成员使用关键字public后跟冒号 (:) 字符来声明。 | protected成员使用关键字protected后跟冒号 (:) 字符来声明。 |
private成员能被子类继承,但不能被子类的对象直接访问。 | public成员可以在子类中被继承并被直接访问。 | protected成员可以在子类中被继承并访问。 |
它为其数据成员提供高安全性。 | 它不为其数据提供任何类型的安全性。 | 它提供的安全性低于private访问说明符。 |
可以在友元功能的帮助下访问private成员。 | public成员可以在有或没有友元功能的帮助下访问。 | protected成员不能通过友元函数访问,它们在类之外是不可访问的,但它们可以被该类的任何子类(派生类),包括派生类及派生类的子类访问。 |
访问说明符已用于确定该类之外的类成员(数据成员和成员函数)的可用性。
在继承中,知道派生类的对象何时可以使用基类中的成员函数很重要,这称为可访问性,访问说明符用于确定这一点。
private、public 和protected 都是C++ 中访问说明符的类型。如果未提及或指定可见性模式,则默认情况下会考虑private模式。
当类的成员被声明为 public 时,就可以从任何地方访问它们。
当类中的成员被声明为protected时,它们就可以在基类和派生类中访问。
当类中的成员被声明为private时,它们只能被基类的成员和友元函数访问。
与public和protected访问说明符相比,private访问说明符为其数据成员提供更多的安全性。
将你的类属性声明为private(尽可能经常)被认为是一种很好的做法,因为这将有助于提高数据安全性。
访问修饰符主要用于数据隐藏和封装,因为它们可以帮助我们控制程序的哪一部分可以访问类的成员。这样就可以防止滥用数据。
总结
对于三种继承,对基类里的private对象处理方式都是一致的,即对派生类都是不可访问的,但它确实被继承了,可以通过基类里的函数来访问。三种继承的不同之处在于:公有继承是将基类的public和protected成员直接继承不改变其属性(即继承后依然是public和potected的),保护继承将基类的public和protected成员直接继承为派生类的protected成员。而私有继承则直接将基类的protected和public成员继承为派生类的private成员。
不难发现,存在着这样的一个优先级:private > protected > public,举个例子:
(1)当继承方式为public时,派生类里所继承的成员就是基类里对应成员的属性(public优先级最低覆盖不了其它关键字)
(2)当继承方式为protected时,派生类里所继承的成员属性只有public会改变为protected(优先级protected > public,protected能覆盖public)
(3)当继承方式为private时,派生类里所继承的成员属性全为private(private优先级最高,相当于覆盖了其它两个优先级)。
作者简介:荔园微风,1981年生,高级工程师,浙大工学硕士,软件工程项目主管,做过程序员、软件设计师、系统架构师,早期的Windows程序员,Visual Studio忠实用户,C/C++使用者,是一位在计算机界学习、拼搏、奋斗了25年的老将,经历了UNIX时代、桌面WIN32时代、Web应用时代、云计算时代、手机安卓时代、大数据时代、ICT时代、AI深度学习时代、智能机器时代,我不知道未来还会有什么时代,只记得这一路走来,充满着艰辛与收获,愿同大家一起走下去,充满希望的走下去。