C++:继承访问属性(public/protected/private)
• 公有继承(public)
公有继承在C++中是最常用的一种继承方式,我们先来看一个示例:
#include<iostream>
using namespace std;
class Father{
public:
Father()=default;
void Father_show1(){
cout<<"调用Father类的public方法:Father_show1"<<endl;
}
protected:
void Father_show2(){
cout<<"调用Father类的protected方法:Father_show2"<<endl;
}
private:
void Father_show3(){
cout<<"调用Father类的private方法:Father_show3"<<endl;
}
}; class Son:public Father{
public:
Son()=default;
void Son_fun1(){
cout<<"调用Son类的public方法:Son_fun1"<<endl;
Father_show1();
Father_show2();
//Father_show3(); //错误:无法调用Father类的private方法
}
protected:
void Son_fun2(){
cout<<"调用Son类的protected方法:Son_fun2"<<endl;
Father_show1();
Father_show2();
//Father_show3(); //错误:无法调用Father类的private方法
}
private:
void Son_fun3(){
cout<<"调用Son类的private方法:Son_fun3"<<endl;
Father_show1();
Father_show2();
//Father_show3();//错误:无法调用Father类的private方法
}
}; int main(){
Son s;
s.Son_fun1(); //正确,只能调用对象的public方法
s.Father_show1();
//s.Son_fun2(); //错误:不能调用对象的protected方法
//s.Father_show2();
//s.Son_fun3(); //错误:不能调用对象的private方法
//s.Father_show3();
return ;
}

对公有继承的理解:
1.三种属性能力的强弱:public<protected<private
2.在C++的继承中,子类会继承父类中除构造函数和析构函数之外的所有成员(正所谓儿子无法继承父亲的生死) 。而公有继承(public)就相当于先将从父类那里继承的全部成员放到子类的public部分,如下:
class Son:public Father{
2 /* 从Father类中继承的所有成员
3 public:
4 public:
5 void Father_show1(){
6 cout<<"调用Father类的public方法:Father_show1"<<endl;
7 }
8 protected:
9 void Father_show2(){
10 cout<<"调用Father类的protected方法:Father_show2"<<endl;
11 }
12 private:
13 void Father_show1(){
14 cout<<"调用Father类的public方法:Father_show1"<<endl;
15 }
16 */
public:
Son()=default;
void Son_fun1(){
cout<<"调用Son类的public方法:Son_fun1"<<endl;
Father_show1();
Father_show2();
//Father_show3();//错误:无法调用Father类的private方法
}
protected:
void Son_fun2(){
cout<<"调用Son类的protected方法:Son_fun2"<<endl;
Father_show1();
Father_show2();
//Father_show3();//错误: 无法调用Father类的private方法
}
private:
void Son_fun3(){
cout<<"调用Son类的private方法:Son_fun3"<<endl;
Father_show1();
Father_show2();
//Father_show3();//错误: 无法调用Father类的private方法
}
};
然后根据三种属性能力的强弱决定成员的属性在子类中究竟是public、protected还是private:
• Father_show1():在Father类中属于public方法,继承到子类Son后放在类的public部分,由于public=public,因此在子类Son中Father_show1()方法仍是public方法
• Father_show2():在Father类中属于protected方法,继承到子类Son后放在类的public部分,由于protected>public,因此子类Son中Father_show2()方法是protected方法
• Father_show3():在Father类中属于private方法,可以理解为“父亲的隐私”,继承到子类Son后放在类的public部分,由于private>public,因此子类Son中Father_show3()方法是private方法。然而正所谓“儿子即使继承了父亲的财产,也无法知晓父亲的隐私”,因此不管儿子以何种方式(public/protected/private)继承父亲的“财产”也无法利用父亲的“隐私”去进行“交易”,换句话说就是父类的private成员虽然可以被子类继承,但子类中的任何成员方法都不能在其函数体中调用这些从父类中继承而来的private成员。因此Son类中的成员方法不管其为与什么部分,都无法调用Father_show3
3.对象只能调用其public部分的成员,而不能调用protected和private部分的成员。因此上例中Son类的对象s可以调用方法Son_fun1()和方法Father_show1(),而无法调用方法Son_fun2()、Son_fun3()、Father_show2()和Father_show3()
• 保护继承(protected)
将上面的示例改为保护继承:
#include<iostream>
using namespace std;
class Father{
public:
Father()=default;
void Father_show1(){
cout<<"调用Father类的public方法:Father_show1"<<endl;
}
protected:
void Father_show2(){
cout<<"调用Father类的protected方法:Father_show2"<<endl;
}
private:
void Father_show3(){
cout<<"调用Father类的private方法:Father_show3"<<endl;
}
}; class Son:protected Father{
public:
Son()=default;
void Son_fun1(){
cout<<"调用Son类的public方法:Son_fun1"<<endl;
Father_show1();
Father_show2();
//Father_show3(); //错误:无法调用Father类的private方法
}
protected:
void Son_fun2(){
cout<<"调用Son类的protected方法:Son_fun2"<<endl;
Father_show1();
Father_show2();
//Father_show3(); //错误:无法调用Father类的private方法
}
private:
void Son_fun3(){
cout<<"调用Son类的private方法:Son_fun3"<<endl;
Father_show1();
Father_show2();
//Father_show3(); //错误:无法调用Father类的private方法
}
}; int main(){
Son s;
s.Son_fun1(); //正确,只能调用对象的public方法
//s.Son_fun2(); //错误:不能调用对象的protected方法
//s.Father_show1();
//s.Father_show2();
//s.Son_fun3(); //错误:不能调用对象的private方法
//s.Father_show3();
return ;
}

对保护继承的理解:
1.三种属性能力的强弱:public<protected<private
2.保护继承相当于先将从父类继承的所用成员都放在子类的protected部分:
class Son:public Father{
/*
3 protected:
4 public:
5 void Father_show1(){
6 cout<<"调用Father类的public方法:Father_show1"<<endl;
7 }
8 protected:
9 void Father_show2(){
10 cout<<"调用Father类的protected方法:Father_show2"<<endl;
11 }
12 private:
13 void Father_show1(){
14 cout<<"调用Father类的public方法:Father_show1"<<endl;
15 }
16 */
public:
Son()=default;
void Son_fun1(){
cout<<"调用Son类的public方法:Son_fun1"<<endl;
Father_show1();
Father_show2();
//Father_show3();//错误:无法调用Father类的private方法
}
protected:
void Son_fun2(){
cout<<"调用Son类的protected方法:Son_fun2"<<endl;
Father_show1();
Father_show2();
//Father_show3();//错误: 无法调用Father类的private方法
}
private:
void Son_fun3(){
cout<<"调用Son类的private方法:Son_fun3"<<endl;
Father_show1();
Father_show2();
//Father_show3();//错误: 无法调用Father类的private方法
}
};
然后和公有继承一样,根据三种属性能力的强弱决定成员的属性在子类中究竟是public、protected还是private:
• 由于public<protected,因此方法Father_show1()在类Son中是protected方法
• 由于protected=protected,因此方法Father_show2()在类Son中是protected方法
• 就像在公有继承中分析的那样,Father_show3()在类Son中虽然是private方法,但Son类中的任何成员方法都不能在其函数体中调用方法Father_show3()
3.对象只能调用public部分的成员,此时方法Father_show1()是对象的protected方法,因此无法像公有继承那样再被显式调用了
• 私有继承
将上面的示例改为私有继承:
#include<iostream>
using namespace std;
class Father{
public:
Father()=default;
void Father_show1(){
cout<<"调用Father类的public方法:Father_show1"<<endl;
}
protected:
void Father_show2(){
cout<<"调用Father类的protected方法:Father_show2"<<endl;
}
private:
void Father_show3(){
cout<<"调用Father类的private方法:Father_show3"<<endl;
}
}; class Son:private Father{
public:
Son()=default;
void Son_fun1(){
cout<<"调用Son类的public方法:Son_fun1"<<endl;
Father_show1();
Father_show2();
//Father_show3(); //错误:无法调用Father类的private方法
}
protected:
void Son_fun2(){
cout<<"调用Son类的protected方法:Son_fun2"<<endl;
Father_show1();
Father_show2();
//Father_show3(); //错误:无法调用Father类的private方法
}
private:
void Son_fun3(){
cout<<"调用Son类的private方法:Son_fun3"<<endl;
Father_show1();
Father_show2();
//Father_show3(); //错误:无法调用Father类的private方法
}
}; int main(){
Son s;
s.Son_fun1(); //正确,只能调用对象的public方法
//s.Son_fun2(); //错误:不能调用对象的protected方法
//s.Son_fun3(); //错误:不能调用对象的private方法
//s.Father_show1();
//s.Father_show2();
//s.Father_show3();
return ;
}

对私有继承的理解:
1.三种属性能力的强弱:public<protected<private
2.私有继承相当于先将从父类继承的所用成员都放在子类的private部分:
class Son:public Father{
2 /*
3 private:
4 public:
5 void Father_show1(){
6 cout<<"调用Father类的public方法:Father_show1"<<endl;
7 }
8 protected:
9 void Father_show2(){
10 cout<<"调用Father类的protected方法:Father_show2"<<endl;
11 }
12 private:
13 void Father_show1(){
14 cout<<"调用Father类的public方法:Father_show1"<<endl;
15 }
16 */
public:
Son()=default;
void Son_fun1(){
cout<<"调用Son类的public方法:Son_fun1"<<endl;
Father_show1();
Father_show2();
//Father_show3();//错误:无法调用Father类的private方法
}
protected:
void Son_fun2(){
cout<<"调用Son类的protected方法:Son_fun2"<<endl;
Father_show1();
Father_show2();
//Father_show3();//错误: 无法调用Father类的private方法
}
private:
void Son_fun3(){
cout<<"调用Son类的private方法:Son_fun3"<<endl;
Father_show1();
Father_show2();
//Father_show3();//错误: 无法调用Father类的private方法
}
};
然后和公有继承一样,根据三种属性能力的强弱决定成员的属性在子类中究竟是public、protected还是private:
• 由于public<private,因此方法Father_show1()在类Son中是private方法,但类Son中的成员方法可以在函数体内调用该方法
• 由于private>protected,因此方法Father_show2()在类Son中是prijvate方法,但类Son中的成员方法可以在函数体内调用该方法
• 就像在公有继承中分析的那样,Father_show3()在类Son中虽然是private方法,但Son类中的任何成员方法都不能在其函数体中调用方法Father_show3()
3.对象只能调用public部分的成员,此时方法Father_show1()是对象的private方法,因此无法像公有继承那样再被显式调用了
QUESTION:保护继承(protected)和私有继承(private)有何不同?
ANSWER:在上面的例子中,我们发现保护继承方式和私有继承方式达到的效果完全一样,难道这两中继承方式没有任何区别吗?我们先来看一个例子:
#include<iostream>
using namespace std;
3 class GrandFather{ //祖父类
4 public:
5 GrandFather()=default;
6 void GrandFather_show(){
7 cout<<"调用GrandFather类的方法:GrandFather_show"<<endl;
8 }
9 };
10 class Father:protected GrandFather{ //父类
11 public:
12 Father()=default;
13 };
14 class Son:public Father{ //子类
15 public:
16 Son()=default;
17 void Son_show(){
18 cout<<"调用Son类的方法:Son_show"<<endl;
19 GrandFather_show();
20 }
21 };
int main(){
Son s;
s.Son_show();
return ;
}

我们发现上面的程序可以顺利运行。这是因为当Father类以保护方式(protected)继承GrandFather类时,GrandFather类中的公有方法GrandFather_show()会以protected方法的形式存在于类Father中,当类Son再以公有方式(public)继承类Father时,方法GrandFather_show()会仍以protected方法的形式存在与类Son中,由于一个类中的成员方法允许在其函数体内调用protected部分的成员,因此系统允许在Son类的成员方法Son_show()调用方法GrandFather_show(),从而使程序顺利运行。
现在我们将程序改为Father类以私有继承的方式继承GrandFather类:
#include<iostream>
using namespace std;
3 class GrandFather{ //祖父类
4 public:
5 GrandFather()=default;
6 void GrandFather_show(){
7 cout<<"调用GrandFather类的方法:GrandFather_show"<<endl;
8 }
9 };
10 class Father:private GrandFather{ //父类
11 public:
12 Father()=default;
13 };
14 class Son:public Father{ //子类
15 public:
16 Son()=default;
17 void Son_show(){
18 cout<<"调用Son类的方法:Son_show"<<endl;
19 GrandFather_show();
20 }
21 };
int main(){
Son s;
s.Son_show();
return ;
}

我们发现程序报错。这是因为当Father类以私有(private)继承GrandFather类时,GrandFather类中的公有方法GrandFather_show()会以private方法的形式存在于类Father中,换句话说方法GrandFather_show()变成了类Father的“隐私”;当类Son再以公有方式(public)继承类Father时,由于“儿子无法利用父亲的“隐私”进行交易”,因此无法在Son类中的任何成员方法中调用GrandFather_show()方法,包括Son_show()。此时如果我们将类Son中成员函数Son_show()中的语句“GrandFather();"注释掉,程序便可以重新顺利执行。
#include<iostream>
using namespace std;
3 class GrandFather{ //祖父类
4 public:
5 GrandFather()=default;
6 void GrandFather_show(){
7 cout<<"调用GrandFather类的方法:GrandFather_show"<<endl;
8 }
9 };
10 class Father:private GrandFather{ //父类
11 public:
12 Father()=default;
13 };
14 class Son:public Father{
15 public:
16 Son()=default;
17 void Son_show(){
18 cout<<"调用Son类的方法:Son_show"<<endl;
19 //GrandFather_show();
20 }
21 };
int main(){
Son s;
s.Son_show();
return ;
}

•总结
| 父类中的访问属性 | 继承方式 | 子类中的访问属性 |
| private | public/protected/private | 不允许访问 |
| public | public | public |
| public | protected | protected |
| public | private | private |
| protected | public | protected |
| protected | protected | protected |
| protected | private | private |
C++:继承访问属性(public/protected/private)的更多相关文章
- C++继承中的public/protected/private
今天杨老师讲到C++的继承的时候用一个表来说明子类继承父类后访问权限的变化,如下表: 注:在本类中,protected与private是相同的,但protected可以被继承,而private却不行. ...
- c/c++ 继承与多态 继承中的public, protected, private
问题:类B私有继承类A,类A有个protected成员,那么在类B的成员函数里是否可以使用类A的protected成员? 可以使用. 估计有的同学说不对吧,类B都私有继承了类A了,怎么还能访问类A的p ...
- [学习笔记]Java的public,protected,private,缺省的作用域
0.引言 Java的访问指示符public,protected,private,缺省可以用来修饰类和方法. 1.作用域如下 具体如下: 作用域 当前类 同一package 子孙类 ...
- C++中public,protected,private派生类继承问题和访问权限问题
C++中public,protected,private派生类继承问题和访问权限问题 当一个子类从父类继承时,父类的所有成员成为子类的成员,此时对父类成员的访问状态由继承时使用的继承限定符决定. 1. ...
- 【转载】C++中public,protected,private访问
第一:private, public, protected 访问标号的访问范围. 假如我们约定: 类内部-----指的是当前类类型的定义中,以及其成员函数的声明和定义中: 类外部-----指的是不在当 ...
- php public protected private属性实例详解
php 类中函数和类变量都有三个属性:public protected private,具体什么时候使用什么属性好纠结,特意找了个实例,这样看起来更清晰. public 表示全局,类内部外部子类都可以 ...
- 【转】C++易混知识点5:实例讲解Public Protected Private作用域,继承的区别和用意
大学生涯,涉及到类的作用域,继承都是用的public 共有继承,当时也没想那么多,觉得共有继承多方便,多简单,反正没有太多的限制,不管是类的成员或者是基类的成员函数都可以访问.没有深究.其实这里面真是 ...
- C# 成员默认访问权限(public、private、protected、internal)
C# 成员默认访问权限(public.private.protected.internal) 来源 https://www.cnblogs.com/yezongjie/p/20181121Access ...
- C++ 类访问控制(public/protected/private)
第一:private, public, protected 访问标号的访问范围. private:只能由1.该类中的函数.2.其友元函数访问. 不能被任何其他访问,该类的对象也不能访问. protec ...
随机推荐
- Redis上踩过的一些坑
来自: http://blog.csdn.net//chenleixing/article/details/50530419 上上周和同事(龙哥)参加了360组织的互联网技术训练营第三期,美团网的DB ...
- 虚拟主机ip配置,nginx.conf文件配置及日志文件切割
今天粗略整理了一下虚拟主机配置,nginx.conf文件的配置,及日志文件的切割,记录如下: nginx虚拟主机配置:1.IP地址配置,2.绑定ip地址和虚拟主机详情:1.ip地址的配置:ifconf ...
- vue项目 使用nginx代理
nginx是一个高性能的HTTP和反向代理服务器.因此常用来做静态资源服务器和后端的反向代理服务器.本文主要记录使用nginx去部署使用vue搭建的前端项目,项目基于vue官方的脚手架vue-cli构 ...
- 垃圾回收相关(深入理解Java虚拟机中的内容)
程序计数器.虚拟机栈和本地方法栈这三个区域属于线程私有的,只存在于线程的生命周期内,线程结束之后也会消失,因此不需要对这三个区域进行垃圾回收.垃圾回收主要是针对 Java 堆和方法区进行. 判断一个对 ...
- jsp el的内置对象
一.el内置对象(11个): pageScope (掌握) requestScope (掌握) applicationScope (掌握) sessionScope (掌握) param (了解) p ...
- 简单直白的去理解AOP,了解Spring AOP,使用 @AspectJ - 读书笔记
AOP = Aspect Oriental Programing 面向切面编程 文章里不讲AOP术语,什么连接点.切点.切面什么的,这玩意太绕,记不住也罢.旨在以简单.直白的方式理解AOP,理解Sp ...
- free命令(buffer与cache区别/linux查看空闲内存)
自:http://www.cnblogs.com/coldplayerest/archive/2010/02/20/1669949.html Linux上free命令的输出. 下面是free的运行 ...
- 关于开发React Native的注意事项
今天在写一个简单的RN的Demo时,一连出现了好几个错误,最后幸亏得以解决,在这里把我踩过的坑以及解决办法分享出来: 1.运行出现错误:Could not connect to development ...
- Docker一键部署Hadoop心得(二)
今天在运行MapReduce程序时,虽然wordcount实例运行成功了,但后面出现了重新使用历史服务器失败的错误 17/12/22 13:33:19 INFO ipc.Client: Retryin ...
- 前尘浮华一场梦 NOI2018 游记
前尘浮华一场梦 NOI2018 哦?我摆弄着手中的键盘,看起来,是要我离开吗?好吧,对于每一个OIer的年,都是以NOI开始,以NOI结束的啊…这个年过的,可不是那么让人舒服呢… 你想听那个人的故事? ...