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++基础知识总结——继承与派生的更多相关文章

  1. c++ 基础知识回顾 继承 继承的本质就是数据的copy

    c++ 基础知识笔记 继承 什么是继承 继承就是子类继承父类的成员属性以及方法 继承的本质就是 数据的复制 是编译器帮我们做了很多操作 class Base { public: Base(){ cou ...

  2. C/C++编程笔记:C++入门知识丨继承和派生

    本篇要学习的内容和知识结构概览 继承和派生的概念 派生 通过特殊化已有的类来建立新类的过程, 叫做”类的派生”, 原有的类叫做”基类”, 新建立的类叫做”派生类”. 从类的成员角度看, 派生类自动地将 ...

  3. C++ 基础 4:继承和派生

    1 继承和派生 在 C++ 中 可重用性是通过继承这一机制实现的.继承允许我们依据另一个类来定义一个类,这使得创建和维护一个应用程序变得更容易.这样做,也达到了重用代码功能和提高执行效率的效果. 当创 ...

  4. java 基础知识十 继承和多态

    java  基础知识十   继承和多态 继承 1.定义: 继承是指声明一些类,可以再进一步声明这些类的子类,而子类具有父类已经拥有的一些方法和属性,这跟现实中的父子关系是十分相似的,所以面向对象把这种 ...

  5. python基础之类的继承与派生、组合、接口与归一化设计、抽象类、子类中调用父类方法

    一.什么是继承 继承是一种创建新的类的方式,新建的类可以继承自一个或者多个父类,原始类称为基类或超类,新建的类称为派生类或子类. 派生:子类继承了父类的属性,然后衍生出自己新的属性,如果子类衍生出的新 ...

  6. java基础知识总结--继承和接口

    什么是继承?什么是接口?他们之间的区别和联系是什么? 什么是继承? 继承是使用已存在的类的定义作为基础建立新类的技术,新类的定义可以增加新的数据或新的功能,也可以用父类的功能.多个类中存在相同属性和行 ...

  7. C++基础知识:继承

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

  8. python基础知识(继承)

    继承的基本语法 class  Class(继承那个基类如果有多个基类用逗号隔开,如果没有就继承object): """ 类的帮助信息""" ...

  9. JavaSE基础知识之继承

    一.概述 继承描述的是事物之间的所属关系,这种关系是: is-a 的关系.例如,图中的兔子属于食草动物,食草动物又属于动物.继承可以使多种事物之间形成一种关系体系,让父类更通用,子类更具体. 1.1  ...

随机推荐

  1. C/C++各种类型int、long、double、char表示范围(最大和最小)

    #include<iostream> #include<string> #include <limits> using namespace std; int mai ...

  2. Linux makefile 课程 非常具体的,和理解

    最近的一项研究Linux根据C计划,我买了一个电话<Linux环境C编程指南>阅读makefile这使他看起来困惑,我可能无法理解. 于是google到了下面这篇文章. 通俗易懂. 然后把 ...

  3. maven+hudson构建集成测试平台

     1.下载hudson.war.2.命令行运行:java -jar hudson.war --httpPort=8070 -Dorg.eclipse.jetty.util.URI.charset=GB ...

  4. Sql数据类型转换

     一.ASCII码值与字符间转换 1.ASCII()与CHAR()       ASCII()返回字符表达式最左端字符的ASCII 码值.在ASCII()函数中,纯数字的字符串可不用''括起来,但含其 ...

  5. Mac在结构quick cocos2d-x编译环境

    关于 Quick 很多其它的使用说明可參考安装文件夹下的 README 文件. Quick-Coco2d-x开发工具 普通情况下,我们通常都会採用Cocos Code IDE作为开发工具来高速开发游戏 ...

  6. JavaScript闭包的一些理解

    原文:JavaScript闭包的一些理解 简单一点的说:闭包就是能够读取其他函数内部变量的函数.那如何实现读取其它函数内部变量呢,大家都知道在JavaScript中内部函数可以访问其父函数中的变量,那 ...

  7. ZOJ3640之简单慨率DP

    Help Me Escape Time Limit: 2 Seconds      Memory Limit: 32768 KB Background     If thou doest well, ...

  8. Access to the temp directory is denied. Identity 'NT AUTHORITY\NETWORK SERVICE' under which XmlSerializer is running does not have sufficient permiss

    造成错误的原因是用bat代码清理系统垃圾时造成的权限丢失而引起的 错误描述 1.An error occurred creating the configuration section handler ...

  9. Archlinux YouCompleteMe+syntastic vim自己主动补全插件,显示缩进和状态栏美化,爽心悦目的vim

    Archlinux 安装和配置vim补全插件YouCompleteMe的过程. 參考: https://github.com/Valloric/YouCompleteMe https://github ...

  10. C#获取远程计算机硬件信息实例(支持linux和windows)

    原文:C#获取远程计算机硬件信息实例(支持linux和windows) 网上关于WMI的资料很多,但一直没有比较全的属性介绍.今天通过反射把所有属性都给弄出来了.   关于WMI的代码就不多说了.   ...