三种访问权限
我们知道C++中的类,有三种访问权限(也称作访问控制),它们分别是public、protected、private。要理解它们其实也很容易,看下面了一个例子。
父类:
<code class="hljs cs has-numbering">class Person { <span class="hljs-keyword">public</span>: <span class="hljs-title">Person</span>(<span class="hljs-keyword">const</span> <span class="hljs-keyword">string</span>& name, <span class="hljs-keyword">int</span> age) : <span class="hljs-title">m_name</span>(name), <span class="hljs-title">m_age</span>(age) { } <span class="hljs-keyword">void</span> ShowInfo() { cout << <span class="hljs-string">"姓名:"</span> << m_name << endl; cout << <span class="hljs-string">"年龄:"</span> << m_age << endl; } <span class="hljs-keyword">protected</span>: <span class="hljs-keyword">string</span> m_name; <span class="hljs-comment">//姓名</span> <span class="hljs-keyword">private</span>: <span class="hljs-keyword">int</span> m_age; <span class="hljs-comment">//年龄</span> };</code>
子类:
<code class="hljs cs has-numbering">class Teacher : <span class="hljs-keyword">public</span> Person { <span class="hljs-keyword">public</span>: <span class="hljs-title">Teacher</span>(<span class="hljs-keyword">const</span> <span class="hljs-keyword">string</span>& name, <span class="hljs-keyword">int</span> age, <span class="hljs-keyword">const</span> <span class="hljs-keyword">string</span>& title) : <span class="hljs-title">Person</span>(name, age), <span class="hljs-title">m_title</span>(title) { } <span class="hljs-keyword">void</span> ShowTeacherInfo() { ShowInfo(); <span class="hljs-comment">//正确,public属性子类可见</span> cout << <span class="hljs-string">"姓名:"</span> << m_name << endl; <span class="hljs-comment">//正确,protected属性子类可见</span> cout << <span class="hljs-string">"年龄:"</span> << m_age << endl; <span class="hljs-comment">//错误,private属性子类不可见</span> cout << <span class="hljs-string">"职称:"</span> << m_title << endl; <span class="hljs-comment">//正确,本类中可见自己的所有成员</span> } <span class="hljs-keyword">private</span>: <span class="hljs-keyword">string</span> m_title; <span class="hljs-comment">//职称</span> };</code>
调用方:
<code class="hljs cpp has-numbering"><span class="hljs-keyword">void</span> test() { Person person(<span class="hljs-string">"张三"</span>, <span class="hljs-number">22</span>); person.ShowInfo(); <span class="hljs-comment">//public属性,对外部可见</span> <span class="hljs-built_in">cout</span> << person.m_name << endl; <span class="hljs-comment">//protected属性,对外部不可见</span> <span class="hljs-built_in">cout</span> << person.m_age << endl; <span class="hljs-comment">//private属性,对外部不可见</span> }</code>
总结
我们对C++类三种方式控制权限总结如下,这与Java中的三种对应的访问权限是一样的。
访问权限 | public | protected | private |
---|---|---|---|
对本类 | 可见 | 可见 | 可见 |
对子类 | 可见 | 可见 | 不可见 |
对外部(调用方) | 可见 | 不可见 | 不可见 |
三种继承方式
C++中继承的方式还有多种,也分别都用public、protected、private表示。这与Java不一样,Java只有继承的概念,默认是public继承的。
1. 三种继承方式不影响子类对父类的访问权限,子类对父类只看父类的访问控制权。如下面三种继承方式都能访问父类中的public和protected成员。
<code class="hljs cs has-numbering">class Teacher : <span class="hljs-comment">/*public*/</span> <span class="hljs-comment">/*protected*/</span> <span class="hljs-keyword">private</span> Person { <span class="hljs-keyword">public</span>: <span class="hljs-title">Teacher</span>(<span class="hljs-keyword">const</span> <span class="hljs-keyword">string</span>& name, <span class="hljs-keyword">int</span> age, <span class="hljs-keyword">const</span> <span class="hljs-keyword">string</span>& title) : <span class="hljs-title">Person</span>(name, age), <span class="hljs-title">m_title</span>(title) { } <span class="hljs-keyword">void</span> ShowTeacherInfo() { ShowInfo(); <span class="hljs-comment">//正确,public属性子类可见</span> cout << <span class="hljs-string">"姓名:"</span> << m_name << endl; <span class="hljs-comment">//正确,protected属性子类可见</span> <span class="hljs-comment">//cout << "年龄:" << m_age << endl; //错误,private属性子类不可见</span> cout << <span class="hljs-string">"职称:"</span> << m_title << endl; <span class="hljs-comment">//正确,本类中可见自己的所有成员</span> } <span class="hljs-keyword">private</span>: <span class="hljs-keyword">string</span> m_title; <span class="hljs-comment">//职称</span> };</code>
2. 继承方式是为了控制子类(也称派生类)的调用方(也叫用户)对父类(也称基类)的访问权限。
public继承
<code class="hljs cs has-numbering">class Teacher : <span class="hljs-keyword">public</span> Person { <span class="hljs-keyword">public</span>: <span class="hljs-title">Teacher</span>(<span class="hljs-keyword">const</span> <span class="hljs-keyword">string</span>& name, <span class="hljs-keyword">int</span> age, <span class="hljs-keyword">const</span> <span class="hljs-keyword">string</span>& title) : <span class="hljs-title">Person</span>(name, age), <span class="hljs-title">m_title</span>(title) { } <span class="hljs-keyword">void</span> ShowTeacherInfo() { ShowInfo(); <span class="hljs-comment">//正确,public属性子类可见</span> cout << <span class="hljs-string">"职称:"</span> << m_title << endl; <span class="hljs-comment">//正确,本类中可见自己的所有成员</span> } <span class="hljs-keyword">private</span>: <span class="hljs-keyword">string</span> m_title; <span class="hljs-comment">//职称</span> };</code>
<code class="hljs avrasm has-numbering">void TestPublic() { Teacher teacher(<span class="hljs-string">"李四"</span>, <span class="hljs-number">35</span>, <span class="hljs-string">"副教授"</span>)<span class="hljs-comment">;</span> teacher<span class="hljs-preprocessor">.ShowInfo</span>()<span class="hljs-comment">;</span> cout << endl<span class="hljs-comment">;</span> teacher<span class="hljs-preprocessor">.ShowTeacherInfo</span>()<span class="hljs-comment">;</span> }</code>
结果:
姓名:李四
年龄:35姓名:李四
年龄:35
职称:副教授
private继承:
<code class="hljs cs has-numbering">class Teacher : <span class="hljs-keyword">private</span> Person { <span class="hljs-keyword">public</span>: <span class="hljs-title">Teacher</span>(<span class="hljs-keyword">const</span> <span class="hljs-keyword">string</span>& name, <span class="hljs-keyword">int</span> age, <span class="hljs-keyword">const</span> <span class="hljs-keyword">string</span>& title) : <span class="hljs-title">Person</span>(name, age), <span class="hljs-title">m_title</span>(title) { } <span class="hljs-keyword">void</span> ShowTeacherInfo() { ShowInfo(); <span class="hljs-comment">//正确,public属性子类可见</span> cout << <span class="hljs-string">"职称:"</span> << m_title << endl; <span class="hljs-comment">//正确,本类中可见自己的所有成员</span> } <span class="hljs-keyword">private</span>: <span class="hljs-keyword">string</span> m_title; <span class="hljs-comment">//职称</span> };</code>
<code class="hljs scss has-numbering">void <span class="hljs-function">TestPrivate()</span> { Teacher <span class="hljs-function">teacher(<span class="hljs-string">"李四"</span>, <span class="hljs-number">35</span>, <span class="hljs-string">"副教授"</span>)</span>; teacher<span class="hljs-class">.ShowInfo</span>(); <span class="hljs-comment">//错误,因为Teacher采用了private的继承方式,外部不可访问。</span> cout << endl; teacher<span class="hljs-class">.ShowTeacherInfo</span>(); }</code>
.
3. public、protected、private三种继承方式,相当于把父类的public访问权限在子类中变成了对应的权限。 如protected继承,把父类中的public成员在本类中变成了protected的访问控制权限;private继承,把父类的public成员和protected成员在本类中变成了private访问控制权。
protected继承:
<code class="hljs cs has-numbering">class Teacher : <span class="hljs-keyword">protected</span> Person { <span class="hljs-keyword">public</span>: <span class="hljs-title">Teacher</span>(<span class="hljs-keyword">const</span> <span class="hljs-keyword">string</span>& name, <span class="hljs-keyword">int</span> age, <span class="hljs-keyword">const</span> <span class="hljs-keyword">string</span>& title) : <span class="hljs-title">Person</span>(name, age), <span class="hljs-title">m_title</span>(title) { } <span class="hljs-keyword">void</span> ShowTeacherInfo() { ShowInfo(); <span class="hljs-comment">//正确,public属性子类可见</span> cout << <span class="hljs-string">"职称:"</span> << m_title << endl; <span class="hljs-comment">//正确,本类中可见自己的所有成员</span> } <span class="hljs-keyword">private</span>: <span class="hljs-keyword">string</span> m_title; <span class="hljs-comment">//职称</span> };</code>
<code class="hljs scss has-numbering">void <span class="hljs-function">TestProtected()</span> { Teacher <span class="hljs-function">teacher(<span class="hljs-string">"李四"</span>, <span class="hljs-number">35</span>, <span class="hljs-string">"副教授"</span>)</span>; teacher<span class="hljs-class">.ShowInfo</span>(); <span class="hljs-comment">//错误,基类Person的ShowInfo此时对Teacher相当于protected的,外部不可以被访问</span> cout << endl; teacher<span class="hljs-class">.ShowTeacherInfo</span>(); }</code>
<code class="hljs cs has-numbering">class Leader : <span class="hljs-keyword">public</span> Teacher { <span class="hljs-keyword">public</span>: <span class="hljs-title">Leader</span>(<span class="hljs-keyword">const</span> <span class="hljs-keyword">string</span>& name, <span class="hljs-keyword">int</span> age, <span class="hljs-keyword">const</span> <span class="hljs-keyword">string</span>& title, <span class="hljs-keyword">string</span> position) : <span class="hljs-title">Teacher</span>(name, age, title), <span class="hljs-title">m_position</span>(position) { } <span class="hljs-keyword">void</span> ShowLeaderInfo() { ShowInfo(); <span class="hljs-comment">//基类Person的ShowInfo此时相当于protected的,但子类仍可以访问</span> ShowTeacherInfo(); <span class="hljs-comment">//ShowTeacherInfo仍然是public的,可以访问</span> cout << m_position << endl; } <span class="hljs-keyword">private</span>: <span class="hljs-keyword">string</span> m_position; };</code>