C/C++基础知识总结——继承与派生
1. 类的继承与派生
1.1 派生类的定义
(1) 定义规范
class 派生类名: 继承方式 基类1名, 继承方式 基类2名...
{
...派生类成员声明;
};
(2) 从以上形式上看可以多继承
(3) 继承方式规定了如何访问从基类继承的成员
(4) 继承的主要目的是实现代码的重用与扩充
(5) 派生类生成过程
① 吸收基类成员
A. 继承后,派生类包含了基类中除构造和析构函数之外的所有成员。构造和析构函数需要重新定义
② 改造基类成员
A. 通过继承方式来控制对基类成员的访问控制
B. 对基类的数据或函数成员进行覆盖和隐藏。隐藏的意思是在派生类中定义一个与基类函数同名(同参数)的函数。(不同参数叫重载)
③ 添加新的成员
2. 访问控制
2.1 公有继承 public
(1) 基类的公有成员和保护成员的访问属性在派生类中不变,基类的私有成员不可直接访问
2.2 私有继承 private
(1) 默认继承方式为私有继承
(2) 基类中的公有成员和保护成员都以私有成员身份出现在派生类中,而基类的私有成员在派生类中不可直接访问
也就是说基类成员都以私有方式存在派生类中,派生类中其他成员可以访问这些。但是在类外无法通过派生类对象访问这些。
经过私有继承后,所有基类成员都成为派生类的私有成员,如果进一步派生的话,基类的全部成员都无法在新的派生类中被直接访问。因此私有继承用的比较少。
2.3 保护继承 protected
(1) 基类的公有和保护成员都以保护成员身份出现在派生类中,基类的私有成员不可继承。
(2) 注意私有继承和保护继承的区别
2.4 静态成员不受继承方式影响,在整个类层次体系中都可以访问
3. 类型兼容规则
3.1 定义:
在需要基类对象的时候,都可以用公有派生类的对象来替代
3.2 类型兼容规则所指的替代包括以下情况。替代后,派生类对象就可以作为基类对象使用,但只能使用从基类继承的成员。
(1) 派生类的对象可以隐含转换为基类对象
(2) 派生类的对象可以初始化基类的引用
(3) 派生类的对象可以隐含转换为基类的指针
例子:
class B{...}
class D: public B{...}
B b1, *pb1;
D d1;
b1 = d1; //实现(1)
B &rb = d1;//实现(2)
pb1 = &d1;//实现(3)
4. 派生类的构造与析构函数
4.1 构造函数
(1) 构造派生类对象时,需要对基类的成员对象和新增成员对象进行初始化。基类的构造函数并没有继承下来,因此需要给派生类添加新的构造函数。派生类对于基类的很多成员对象不能访问,因此需要调用基类的构造函数来对基类中不能访问的成员进行初始化。在构造派生类对象时,首先调用基类的构造函数,然后构造初始化参数表,然后执行函数体。
(2) 语法:
派生类名::派生类名(参数表):
基类名1(基类1初始化参数表)...,基类名n(基类n初始化参数表),
成员对象名1(成员对象名1初始化参数表),...,成员对象m(成员对象m参数表)
{
...其他初始化工作
}
(3) 派生类构造函数执行一般次序如下
① 调用基类构造函数,按照继承时声明顺序
② 对派生类新增的成员对象初始化,按照类中声明顺序
③ 执行构造函数体
4.2 复制构造函数
4.3 析构函数
(1) 执行顺序与构造函数相反。
① 先执行析构函数体
② 再调用派生类中类对象的析构函数体
③ 调用基类的析构函数
5. 派生类成员的标识与访问
5.1 作用域分辨符 ::
(1) 如果派生类声明了与基类成员函数同名的新函数,即使函数参数不同,从基类中继承的同名函数的所有重载形式都会被隐藏。只有在相同作用域中定义的函数才可以重载。。。(这个地方???)
(2) 如果某个派生类继承了多个基类,在这些基类中有同名的数据。此时访问方式为:
class base1
{
int a;
}
class base2
{
int a;
}
class derived: public base1, public base2{
}
derived d;
d.base1::var = ;//以这种方式!切记!
d.base2::var = ;
(3) 还是一个派生类derived的两个父类base1、base2是由同一个基类base0派生的,那么,base1和base2中都有base0的一个副本,而只想要一个副本。那就需要用到虚基类。
5.2 虚基类
(1) 如果将上面讲的base0设为虚基类,则不同路径继承到derived的同名数据在内存中只有一个副本,同一个函数名只有一个映射。这样就解决了同名成员唯一标识问题。
(2) 语法:
class 派生类名:virtual 继承方式 基类名
(3) 例子:
class base0
{
int var0;
}
class base1:virtual public base0
{
}
class base2:virtual public base0
{
}
class derived: public base1, public base2{
}
derived d;
d.var0 = ;//只有一个var0的副本
5.3 虚基类及派生类的构造函数
(1) 如果上面的例子中虚基类没有默认构造函数就比较麻烦了,要改成下面的形式
class base0{
base0(int var):var0(var){}
int var0;
};
class base1: virtual public base0
{
base1(int var):base0(var){}
}
class base2:virtual public base0
{
base2(int bar):base0(var){}
}
class derived:public base1, public base2
{
derived(int var):base0(var),base1(var),base2(var){};
}
(2) 虽然已经改造了,但是不用担心base0的var0会初始化三次,因为在创建derived的对象时,首先调用原始基类的构造函数,之后的base1和base2中对base0的构造函数都被自动忽略了。
(3) 构造一个类对象的一般顺序为:
① 如果该类有直接或间接的虚基类,执行虚基类的构造函数
② 如果还有其他基类,按照继承声明中的顺序,执行构造函数,但不执行虚基类的构造函数
③ 按照类定义中的顺序,对派生类的成员对象进行初始化。对于类对象成员,如果出现在构造函数初始化列表中,则以指定的参数执行构造函数,如未出 现,则执行默认构造函数;对于基本数据类型,如果出现在构造函数初始化列表中,则用指定的值初始化,否则什么也不做
④ 执行构造函数的函数体
作者:viczzx 出处:http://www.cnblogs.com/zixuan-zhang 欢迎转载,也请保留这段声明。谢谢!
C/C++基础知识总结——继承与派生的更多相关文章
- c++ 基础知识回顾 继承 继承的本质就是数据的copy
c++ 基础知识笔记 继承 什么是继承 继承就是子类继承父类的成员属性以及方法 继承的本质就是 数据的复制 是编译器帮我们做了很多操作 class Base { public: Base(){ cou ...
- C/C++编程笔记:C++入门知识丨继承和派生
本篇要学习的内容和知识结构概览 继承和派生的概念 派生 通过特殊化已有的类来建立新类的过程, 叫做”类的派生”, 原有的类叫做”基类”, 新建立的类叫做”派生类”. 从类的成员角度看, 派生类自动地将 ...
- C++ 基础 4:继承和派生
1 继承和派生 在 C++ 中 可重用性是通过继承这一机制实现的.继承允许我们依据另一个类来定义一个类,这使得创建和维护一个应用程序变得更容易.这样做,也达到了重用代码功能和提高执行效率的效果. 当创 ...
- java 基础知识十 继承和多态
java 基础知识十 继承和多态 继承 1.定义: 继承是指声明一些类,可以再进一步声明这些类的子类,而子类具有父类已经拥有的一些方法和属性,这跟现实中的父子关系是十分相似的,所以面向对象把这种 ...
- python基础之类的继承与派生、组合、接口与归一化设计、抽象类、子类中调用父类方法
一.什么是继承 继承是一种创建新的类的方式,新建的类可以继承自一个或者多个父类,原始类称为基类或超类,新建的类称为派生类或子类. 派生:子类继承了父类的属性,然后衍生出自己新的属性,如果子类衍生出的新 ...
- java基础知识总结--继承和接口
什么是继承?什么是接口?他们之间的区别和联系是什么? 什么是继承? 继承是使用已存在的类的定义作为基础建立新类的技术,新类的定义可以增加新的数据或新的功能,也可以用父类的功能.多个类中存在相同属性和行 ...
- C++基础知识:继承
1.继承的概念 面向对象中的继承指类之间的父子关系子类拥有父类的所有成员变量和成员函数子类就是一种特殊的父类子类对象可以当作父类对象使用子类可以拥有父类没有的方法和属性 2.C++中的访问级别与继承p ...
- python基础知识(继承)
继承的基本语法 class Class(继承那个基类如果有多个基类用逗号隔开,如果没有就继承object): """ 类的帮助信息""" ...
- JavaSE基础知识之继承
一.概述 继承描述的是事物之间的所属关系,这种关系是: is-a 的关系.例如,图中的兔子属于食草动物,食草动物又属于动物.继承可以使多种事物之间形成一种关系体系,让父类更通用,子类更具体. 1.1 ...
随机推荐
- vi/vim编辑器的基本操作
vi/vim编辑器的基本操作 Contents 1. 工具准备(下载gvim) 2. vi/vim基本入门 2.1. 安装 2.2. 基本使用 3. vi/vim基本命令表 1 工具准备(下载gvim ...
- XML的序列化和反序列化 详细介绍
为什么要做序列化和反序列化? 一个回答: 我们都知道对象是不能在网络中直接传输的,不过还有补救的办法.XML(Extensible Markup Language)可扩展标记语言,本身就被设计用来存储 ...
- 在LINQ中实现多条件联合主键LEFT JOIN
我昨天遇到一个LINQ下使用多条件比对产生LEFT JOIN的问题,经过深入研究,终于解决了,也让我学到了新的东西,特地拿来分享. 实例:有一张库存异常变更视图KCYD,仓库ID[Ckid]和物品ID ...
- crawler_基础之_httpclient 访问网络资源
先粘贴一个 简单版的,后期再修改 pom文件 <dependency> <groupId>org.apache.httpcomponents</groupId> & ...
- elasticsearch的rest搜索--- 查询
目录: 一.针对这次装B 的解释 二.下载,安装插件elasticsearch-1.7.0 三.索引的mapping 四. 查询 五.对于相关度的大牛的文档 四. 查询 1. 查询的官网的文档 ...
- hdu 3709 数字dp(小思)
http://acm.hdu.edu.cn/showproblem.php?pid=3709 Problem Description A balanced number is a non-negati ...
- linux中如何用root去修改其他用户的密码
linux中如何用root去修改其他用户的密码 昨天linux实验课,我有很多自己想摸索的东西.今天周五,本是下午一二节是编译的实验,可强烈的欲望让我今早就来实验室了,摸索吧,碰到了这个问题.... ...
- 一步一步写算法(之挑选最大的n个数)
原文:一步一步写算法(之挑选最大的n个数) [ 声明:版权所有,欢迎转载,请勿用于商业用途. 联系信箱:feixiaoxing @163.com] 从一堆数据中挑选n个最大的数,这个问题是网上流传的 ...
- Mysql C语言API编程入门讲解
原文:Mysql C语言API编程入门讲解 软件开发中我们经常要访问数据库,存取数据,之前已经有网友提出让鸡啄米讲讲数据库编程的知识,本文就详细讲解如何使用Mysql的C语言API进行数据库编程. ...
- 5. SQL Server数据库性能监控 - 当前请求
原文:5. SQL Server数据库性能监控 - 当前请求 对于在线运行的系统,当前数据库性能监控,通常监视以下几点: (1) 是否有阻塞 (Blocking); (2) 是否有等待 (Waitin ...