C++基础知识:继承
1.继承的概念
面向对象中的继承指类之间的父子关系
子类拥有父类的所有成员变量和成员函数
子类就是一种特殊的父类
子类对象可以当作父类对象使用
子类可以拥有父类没有的方法和属性

2.C++中的访问级别与继承
public继承
父类成员在子类中保持原有访问级别
private继承
父类成员在子类中变为private成员
注意:
C++中class的继承默认为private继承
private继承的子类拥有父类的所有成员
private继承使得父类的所有成员在子类中变为private成员

3.类的protected成员
protected成员可以在子类中被访问,但不能在外界被访问
protected成员的访问权限介于public和private之间

4.类成员访问级别设置的原则
需要被外界访问的成员直接设置为public
只能在当前类中访问的成员设置为private
只能在当前类和子类中访问的成员设置为protected
private成员在子类中依然存在,但是却无法访问到!

5.继承中的构造与析构
①赋值兼容性原则
子类对象可以当作父类对象使用
子类对象可以直接赋值给父类对象
子类对象可以直接初始化父类对象
父类指针可以直接指向子类对象
父类引用可以直接引用子类对象
子类是就是特殊的父类:

②类在C++编译器的内部可以理解为结构体,子类是由父类成员叠加子类新成员得到的:

③在子类对象构造的时候需要调用父类构造函数对其继承得来的成员进行初始化:

④在子类对象析构的时候需要调用父类析构函数对其继承得来的成员进行清理

子类对象在创建时会首先调用父类的构造函数
父类构造函数执行结束后,执行子类的构造函数
当父类的构造函数有参数时,需要在子类的初始化列表中显示调用
析构函数调用的先后顺序与构造函数相反
⑤继承与组合的混搭:
如果一个类继承自父类并且有其它的对象作为成员,那么构造函数如何调用?
口诀:先父母,后客人,再自己。

⑥当子类成员变量与父类成员变量同名时:
子类依然从父类继承同名成员
在子类中通过作用域分别符::进行同名成员区分
同名成员存储在内存中的不同位置

6.继承与多态
①函数重写:
在子类中定义与父类中原型相同的函数
函数重写只发生在父类与子类之间
父类中被重写的函数依然会继承给子类
默认情况下子类中重写的函数将隐藏父类中的函数
通过作用域分辨符::可以访问到父类中被隐藏的函数


②当函数重写遇上赋值兼容性原则

问题所在:
C++与C相同,是静态编译型语言
在编译时,编译器自动根据指针的类型判断指向的是一个什么样的对象
所以编译器认为父类指针指向的是父类对象(根据赋值兼容性原则,这个假设合理)
由于程序没有运行,所以不可能知道父类指针指向的具体是父类对象还是子类对象
从程序安全的角度,编译器假设父类指针只指向父类对象,因此编译的结果为调用父类的成员函数

在编译这个函数的时候,编译器不可能知道指针 p 究竟指向了什么。
但是编译器没有理由报错。于是,编译器认为最安全的做法是编译到父类的print函数,因为父类和子类肯定都有相同的print函数。
③多态应用:C++支持两种多态性:编译时多态性,运行时多态性。
a.编译时多态性: 通过函数重载和运算符重载来实现的。
b 运行时多态性:通过继承和虚函数来实现的。
根据实际的对象类型来判断重写函数的调用
如果父类指针指向的是父类对象则调用父类中定义的函数
如果父类指针指向的是子类对象则调用子类中定义的重写函数

C++中的多态支持:
C++中通过virtual关键字对多态进行支持(传说中的虚函数)
使用virtual声明的函数被重写后即可展现多态特性
C++中多态的实现原理
当类中声明虚函数时,编译器会在类中生成一个虚函数表
虚函数表是一个存储类成员函数指针的数据结构
虚函数表是由编译器自动生成与维护的
virtual成员函数会被编译器放入虚函数表中
存在虚函数时,每个对象中都有一个指向虚函数表的指针


虚函数的深入理解:

通过虚函数表指针VPTR调用重写函数是在程序运行时进行的,因此需要通过寻址操作才能确定真正应该调用的函数。
而普通成员函数是在编译时就确定了调用的函数。在效率上,虚函数的效率要低很多。
对象中的VPTR指针什么时候被初始化?
对象在创建的时候由编译器对VPTR指针进行初始化
只有当对象的构造完全结束后VPTR的指向才最终确定
父类对象的VPTR指向父类虚函数表
子类对象的VPTR指向子类虚函数表
结论:构造函数中调用虚函数无法实现多态。
虚函数:在基类中被声明为virtual,并在派生类中重新定义的成员函数,可实现成员函数的动态重载
纯虚函数:纯虚函数是只声明函数原型,而故意不定义函数体的虚函数。
面向对象中的抽象类:抽象类可用于表示现实世界中的抽象概念,包含纯虚函数的类称为抽象类
抽象类是一种只能定义类型,而不能产生对象的类
抽象类只能被继承并重写相关函数
抽象类的直接特征是纯虚函数
抽象类不能用于定义对象
抽象类只能用于定义指针和引用
抽象中的纯虚函数必须被子类重写

④函数的重载/重写

C++基础知识:继承的更多相关文章
- JAVA基础知识|继承的几个问题
1.子类从父类继承了什么? 子类拥有父类非private的属性,方法. 2.子类可以操作父类的非private属性吗? 子类不能继承父类的私有属性,但是如果父类中的非private方法影响到了私有属性 ...
- java基础知识—继承
1.不能被继承的父类成员: private成员.子类与父类不在同包,使用默认访问权限的成员.构造方法. 2.访问修饰符: 访问修饰符 本类 同包 子类 其它 ...
- 20151024_004_C#基础知识(C#中的访问修饰符,继承,new关键字,里氏转换,is 和 as,多态,序列化与反序列化)
1:C#中的访问修饰符 public: 公共成员,完全公开,没有访问限制. private: 私有的,只能在当前类的内部访问. protected: 受保护的,只能在当前类的内部以及该类的子类中访问. ...
- Servlet学习笔记【1】--- 背景和基础知识(CGI、Web服务器发展史、Servlet简介、任务、继承结构)
本文主要讲Servlet的基础知识和背景知识. 1 CGI简介 CGI(Common Gateway Interface 公共网关接口)是WWW技术中最重要的技术之一,有着不可替代的重要地位.CGI是 ...
- c++ 基础知识回顾 继承 继承的本质就是数据的copy
c++ 基础知识笔记 继承 什么是继承 继承就是子类继承父类的成员属性以及方法 继承的本质就是 数据的复制 是编译器帮我们做了很多操作 class Base { public: Base(){ cou ...
- 《Java核心技术·卷Ⅰ:基础知识(原版10》学习笔记 第5章 继承
<Java核心技术·卷Ⅰ:基础知识(原版10>学习笔记 第5章 继承 目录 <Java核心技术·卷Ⅰ:基础知识(原版10>学习笔记 第5章 继承 5.1 类.超类和子类 5.1 ...
- 【干货】用大白话聊聊JavaSE — ArrayList 深入剖析和Java基础知识详解(二)
在上一节中,我们简单阐述了Java的一些基础知识,比如多态,接口的实现等. 然后,演示了ArrayList的几个基本方法. ArrayList是一个集合框架,它的底层其实就是一个数组,这一点,官方文档 ...
- java基础知识 多线程
package org.base.practise9; import org.junit.Test; import java.awt.event.WindowAdapter; import java. ...
- Linux基础知识整理
一.基础知识 1.Linux简介 Linux是一套免费使用和自由传播的类Unix操作系统,是一个基于POSIX和UNIX的多用户.多任务.支持多线程和多CPU的操作系统.它能运行主要的UNIX工具软件 ...
- 基础知识《十》unchecked异常和checked异常
运行时异常在运行期间才能被检查出来,一般运行期异常不需要处理.也称为unchecked异常.Checked异常在编译时就能确定,Checked异常需要自己处理. checked 异常也就是我们经常遇到 ...
随机推荐
- 绕过cookies进行登录并封装请求方法
之前写了一篇使用session跨请求保持会话的帖子,这次在它的基础上对请求方法简单封装一下,可以达到复用的效果 1.先定义登录方法 在登录方法中利用session跨请求保持会话,并返回session, ...
- Python学习笔记之参数解析
python提供了两种方法进行命令行的参数解析,分别是getopt和optparse类中的模块OptionParser,下面分别详细了解这两个模块: 1.getopt模块 首先复习C语言的命令行解析: ...
- Top 命令解析
TOP是一个动态显示过程,即可以通过用户按键来不断刷新当前状态.如果在前台执行该命令,它将独占前台,直到用户终止该程序为止.比较准确的说,top命令提供了实时的对系统处理器的状态监视.它将显示系统中C ...
- 2017-2018-2 20165303 实验三《Java面向对象程序设计》实验报告
实验三 敏捷开发与XP实践-1 实验要求 实验三 敏捷开发与XP实践 http://www.cnblogs.com/rocedu/p/4795776.html, Eclipse的内容替换成IDEA 参 ...
- OnSen UI结合AngularJs打造”美团"APP底部导航栏 --Hybrid App
1.页面效果图:(点击底部导航按钮,可切换到不同的页面) 演示地址:http://www.nxl123.cn/bokeyuan/2018080301/meiTuanDemo/ 2.项目目录结构 3.核 ...
- java学习进度
上周日玩的比较high,忘记写进度报告,今天补上.通过这些天的学习,我对java有了初步的认识,java和c有很多的不同和相同之处,然后就是java的代码在记事本里写,等慢慢深入之后又可以用eclip ...
- asyncio创建协程解析——分析廖雪峰的Python教程之创建WEB服务(转)
第一步,搭建开发环境 所需第三方库: aiohttp,异步 Web 开发框架:jinja2,前端模板引擎:aiomysql,异步 mysql 数据库驱动 所需内置库: logging,系统日志:asy ...
- lvalue require as increment operand
#include<stdio.h> #include<stdlib.h> int main() { char source[]="hello"; //创建一 ...
- Thymeleaf使用bootstrap及其bootstrap相关插件(二)
接上文http://www.cnblogs.com/conswin/p/7929772.html 接下来bootstrap-datepicker的简单使用. 1.引入添加js 和 css 2.然后是h ...
- Spring Boot系列之配置日志输出等级
我们都知道Spring boot 默认使用 logback作进行日志输出,那么 在配置Spring boot日志输出时有两种方式: 通过application.properties 配置文件的方式来配 ...