C++的三种继承方式详解以及区别
C++的三种继承方式详解以及区别
前言
我发现有时候概念性的东西,理解起来还是很难的,于是本文用简单的几个例子,来说明这三种不同的继承方式,他们之前的区别~
一、public继承
基类的
public和protected成员的访问属性在派生类中保持不变,但基类的private成员不可直接访问。派生类中的成员函数可以直接访问基类中的
public和protected成员,但不能直接访问基类的private成员。通过派生类的对象访问从基类继承的成员,只能访问
public成员。
#include<iostream>
using namespace std;
class CFather
{
public:
int m_testA{0};
protected:
int m_testB{0};
private:
int m_testC{0};
};
class CSon: public CFather
{
void test()
{
m_testA = 1; // 编译正确 :public 继承后,在内部或者外部都可以访问public成员
m_testB = 1; // 编译正确 :public 继承后,在内部可以访问protected成员
m_testC = 1; // 编译错误 :无论哪种继承,都无法访问private成员
}
};
int main()
{
CSon _test;
_test.m_testA = 2; // 编译正确 :public 继承后,在内部或者外部都可以访问public成员
_test.m_testB = 2; // 编译错误 :public 继承后,在外部无法访问protected成员
_test.m_testC = 2; // 编译错误 :无论哪种继承,都无法访问private成员
system("pause");
return 0;
}
二、protected继承
- 基类的
public和protected成员都以private身份出现在派生类中,但基类的private成员不可直接``访问。 - 派生类中的成员函数可以直接访问基类中的
public和protected成员,但不能直接访问基类的private成员。 - 通过派生类的对象
不能直接访问从基类继承的任何成员。
#include<iostream>
using namespace std;
class CFather
{
public:
int m_testA{0};
protected:
int m_testB{0};
private:
int m_testC{0};
};
class CSon: protected CFather
{
void test()
{
m_testA = 1; // 编译正确 :protected 继承后,在内部可以访问public成员
m_testB = 1; // 编译正确 :protected 继承后,在内部可以访问protected成员
m_testC = 1; // 编译错误 :无论哪种继承,都无法访问private成员
}
};
int main()
{
CSon _test;
_test.m_testA = 2; // 编译错误 :protected 继承后,在外部无法访问public成员
_test.m_testB = 2; // 编译错误 :protected 继承后,在外部无法访问protected成员
_test.m_testC = 2; // 编译错误 :无论哪种继承,都无法访问private成员
system("pause");
return 0;
}
此时,可以这么理解为 派生类 通过 protected继承 基类 之后 ,基类 中的 public变成了protected,其他保持原样。
class CFather
{
protected:// proteced 继承之后public变成了 proteced
int m_testA{0};
protected:
int m_testB{0};
private:
int m_testC{0};
};
三、private继承
- 基类的
public和protected成员都以private身份出现在派生类中,但基类的private成员不可直接访问。 - 派生类中的成员函数可以
直接访问基类中的public和protected成员,但不能直接访问基类的private成员。 - 通过派生类的对象
不能直接访问从基类继承的任何成员。
#include<iostream>
using namespace std;
class CFather
{
public:
int m_testA{0};
protected:
int m_testB{0};
private:
int m_testC{0};
};
class CSon: private CFather
{
void test()
{
m_testA = 1; // 编译正确 :private 继承后,在内部可以访问public成员
m_testB = 1; // 编译正确 :private 继承后,在内部可以访问protected成员
m_testC = 1; // 编译错误 :无论哪种继承,都无法访问private成员
}
};
int main()
{
CSon _test;
_test.m_testA = 2; // 编译错误 :private 继承后,在外部无法访问public成员
_test.m_testB = 2; // 编译错误 :private 继承后,在外部无法访问protected成员
_test.m_testC = 2; // 编译错误 :无论哪种继承,都无法访问private成员
system("pause");
return 0;
}
此时,可以这么理解为 派生类 通过 private继承 基类 之后 ,基类 中的 public与protected变成了private,其他保持原样。
class CFather
{
private:// private 继承之后public变成了 private
int m_testA{0};
private:// private 继承之后protected变成了 private
int m_testB{0};
private:
int m_testC{0};
};
四、三者区别
public继承方式
- 基类中所有
public成员在派生类中为public属性; - 基类中所有
protected成员在派生类中为protected属性; - 基类中所有
private成员在派生类中不能使用。
- 基类中所有
protected继承方式
- 基类中的所有
public成员在派生类中为protected属性; - 基类中的所有
protected成员在派生类中为protected属性; - 基类中的所有
private成员在派生类中不能使用。
- 基类中的所有
private继承方式
- 基类中的所有
public成员在派生类中均为private属性; - 基类中的所有
protected成员在派生类中均为private属性; - 基类中的所有
private成员在派生类中不能使用。
- 基类中的所有
下表汇总了不同继承方式对不同属性的成员的影响结果
| 继承方式/基类成员 | public成员 | protected成员 | private成员 |
|---|---|---|---|
| public继承 | public | protected | 不可见 |
| protected继承 | protected | protected | 不可见 |
| private继承 | private | private | 不可见 |
五、总结
1.不管继承方式如何,基类中的 private 成员在派生类中始终不能使用(不能在派生类的成员函数中访问或调用)。
2.如果希望基类的成员能够被派生类继承并且毫无障碍地使用,那么这些成员只能声明为 public 或 protected;只有那些不希望在派生类中使用的成员才声明为 private。
3.如果希望基类的成员既不向外暴露(不能通过对象访问),还能在派生类中使用,那么只能声明为 protected。
4.基类成员在派生类中的访问权限不得高于继承方式中指定的权限。例如,当继承方式为 protected 时,那么基类成员在派生类中的访问权限最高也为 protected,高于 protected 的会降级为 protected,但低于 protected 不会升级。再如,当继承方式为 public 时,那么基类成员在派生类中的访问权限将保持不变。
后话
我们这里说的是基类的 private 成员不能在派生类中使用,并没有说基类的 private 成员不能被继承。实际上,基类的 private 成员是能够被继承的,并且(成员变量)会占用派生类对象的内存,它只是在派生类中不可见,导致无法使用罢了。private 成员的这种特性,能够很好的对派生类隐藏基类的实现,以体现面向对象的封装性。由于 private 和 protected 继承方式会改变基类成员在派生类中的访问权限,导致继承关系复杂,所以实际开发中我们一般使用 public。
C++的三种继承方式详解以及区别的更多相关文章
- python selenium 三种等待方式详解[转]
python selenium 三种等待方式详解 引言: 当你觉得你的定位没有问题,但是却直接报了元素不可见,那你就可以考虑是不是因为程序运行太快或者页面加载太慢造成了元素不可见,那就必须要加等待 ...
- js的2种继承方式详解
js中继承可以分为两种:对象冒充和原型链方式 一.对象冒充包括三种:临时属性方式.call()及apply()方式1.临时属性方式 复制代码代码如下: function Person(name){ ...
- Python selenium 三种等待方式详解
1. 强制等待第一种也是最简单粗暴的一种办法就是强制等待sleep(xx),强制让闪电侠等xx时间,不管凹凸曼能不能跟上速度,还是已经提前到了,都必须等xx时间.看代码: # -*- coding: ...
- JavaScript五种继承方式详解
本文抄袭仅供学习http://www.ruanyifeng.com/blog/2010/05/object-oriented_javascript_inheritance.html 一. 构造函数绑定 ...
- Python selenium 三种等待方式详解(必会)
很多人在群里问,这个下拉框定位不到.那个弹出框定位不到…各种定位不到,其实大多数情况下就是两种问题:1 有frame,2 没有加等待.殊不知,你的代码运行速度是什么量级的,而浏览器加载渲染速度又是什么 ...
- SQL-----数据库三种删除方式详解
第一种 使用delete 语句 特点: delete 属于数据库操纵语言DML,表示删除表中的数据, 删除过程是每次从表中删除一行,并把该行删除操作作为事务记录在日志中保存 可以配合事件(tran ...
- Selenium 三种等待方式详解
我们在做WEB自动化时,一般要等待页面元素加载完成后,才能执行操作,否则会报找不到元素的错误,这样就要求我们在有些场景下加等待时间. 我们平常用到的有三种等待方式: 强制等待 隐式等待 显示等待 一. ...
- Selenium:三种等待方式详解
我们在做WEB自动化时,一般要等待页面元素加载完成后,才能执行操作,否则会报找不到元素的错误,这样就要求我们在有些场景下加等待时间. 我们平常用到的有三种等待方式: 强制等待 隐式等待 显示等待 一. ...
- Spring事务Transaction配置的五种注入方式详解
Spring事务Transaction配置的五种注入方式详解 前段时间对Spring的事务配置做了比较深入的研究,在此之间对Spring的事务配置虽说也配置过,但是一直没有一个清楚的认识.通过这次的学 ...
随机推荐
- 使用VS Code编译Marlin固件
参考:https://marlinfw.org/docs/basics/install_platformio_vscode.html 前言 在阅读本文之前,您应该已经阅读了使用 PlatformIO ...
- python -sorted 学习
跟C++ STL中的sort的用法类似,sorted用来对列表进行排序 比如: list = [3,4,82,66,22,11] 用sorted(list),就会对对list这个表进行排序 如果,so ...
- python 模块和包的基础知识
1.常见的场景:一个模块就是一个包含了python定义和声明的文件,文件名就是模块名字加上.py的后缀 2.为了方便管理,我们通常将程序分成一个个的文件,这样做程序的结构更清晰,方便管理.这时我们不仅 ...
- Java并发机制(2)--synchronized与Lock
本内容整理自:博客园-海 子-java并发编程系列-http://www.cnblogs.com/dolphin0520/category/602384.html 1.基础: 1.什么时候出现线程安全 ...
- 分布式集群中为什么会有 Master?
在分布式环境中,有些业务逻辑只需要集群中的某一台机器进行执行,其他的机 器可以共享这个结果,这样可以大大减少重复计算,提高性能,于是就需要进行 leader 选举.
- PACT 在微服务架构中的用途是什么?
PACT 是一个开源工具,允许测试服务提供者和消费者之间的交互,与合同隔离, 从而提高微服务集成的可靠性. 微服务中的用法 用于在微服务中实现消费者驱动的合同. 测试微服务的消费者和提供者之间的消费者 ...
- centos云服务器配置redis外网可访问
找到这行,注释 bind 127.0.0.1 #bind 127.0.0.1 找到这行,修改 protected-mode yes protected-mode no 重启服务 ./redis-ser ...
- 内网穿透系列-Go语言
一.介绍 软件在KCP出现后进行了重构,将其底层UDP支持替换为了KCP,使其效率大大提高,在某些恶劣的网络环境下依旧能有不错的效果.当然,它也是支持TCP模式的,另外它也是支持加密的,在P2P打洞失 ...
- 使用jquery-webcam插件,实现人脸采集并转base64
项目需求:在ie或chrome浏览器下,调用电脑摄像头(确保使用的是笔记本电脑,或者摄像头功能正常使用的台式机),进行人脸图像采集预览,并将图片的base64码传入到后台进行后续操作.该demo适用于 ...
- HTML5 & CSS3 内容收集(1)
1. HTML发展历史介绍 2. 浏览器支持 2.1 新增标签支持 在html5 中新增了很多的标签,其中包括8个新增语义结构标签.header, section, footer, aside, na ...