从一个类派生出另一个类时,原始类称为基类,继承类称为派生类.
派生类需要自己的构造函数;派生类可以根据需要添加额外的成员和成员函数. 派生类不能直接访问基类的私有成员,必须依赖基类的方法经行访问.
创建派生类对象时,程序首先创建基类对象. 不显示调用基类的构造函数时将使用默认的基类构造函数.
派生类的构造函数要点如下:
- 首先创建基类对象
- 派生类构造函数应通过成员初始化列表将基类信息传递给基类构造函数
- 派生类构造函数应初始化派生类新增的数据成员.
派生类和基类之间的特殊关系:
- 派生类对象可以使用基类的方法,条件是方法不是私有的
- 基类指针可以不进行显示类型转换的情况下指向派生类
- 基类引用可以不进行显示类型转换的条件下引用派生类对象 (然而 基类指针或者引用只能调用基类的方法)
方法的行为应取决于调用该方法的对象,这种较为复杂的行为称为多态,同一个方法随上下文而异
实现多态的机制:
- 派生类中重定义基类的方法
- 使用虚方法
在子类的析构函数中包含了某些操作则基类中必须提供一个虚的析构函数
静态联编和动态联编将源代码中的函数调用 解释 为 执行特定的函数代码块被称为函数名联编。
编译器必须查看函数参数以及函数名才能确定使用哪个函数。然而, C/ C++ 编译器可以在编译过程完成这种联编。 在编译 过程中进行联编被称为静态联编, 又称为早期联编 .
虚函数使这项工作变得更困难。使用哪一个函数是不能在编译时确定的, 因为编译器不知道用户将 选择 哪种 类型的对象。 所以,编译器必须生成能够在程序运行时选择正确的虚方法的代码, 这被称为动态联编, 又称为晚期联编。
在 C++ 中, 动态联编与通过指针和引用调用方法相关,
将 派生 类 引用 或 指针 转换 为 基 类 引用 或 指针 被称为 向上 强制 转换( upcasting), 这使 公有 继承 不需要 进行 显 式 类型 转换。
相反 的 过程—— 将基类指针或引用转换为派生类指针或引用—— 称为 向下强制转换( downcasting)。 如果不使用显式类型转换, 则 向下强制转换 是不允许的。向下可能带来不安全的操作.
编译器对非虚方法 使用 静态联编。
隐式 向上强制转换 使 基类指针或引用 可以指向基类对象或派生类对象, 因此 需要 动态联 编。c++使用虚成员函数满足这种需求
虚函数的工作原理
虚函数的特点:
- 在 基 类 方法 的 声明 中 使用 关键字 virtual 可使 该 方法 在 基 类 以及 所有 的 派生 类( 包括 从 派生 类 派生 出 来的 类) 中 是 虚 的。
- 如果 使用 指向 对象 的 引用 或 指针 来 调用 虚 方法, 程序 将使 用为 对象 类型 定义 的 方法, 而 不使 用为 引用 或 指针 类型 定义 的 方法。 这 称为 动态 联 编 或 晚期 联 编。 这种 行为 非常 重要, 因为 这样 基 类 指针 或 引用 可以 指向 派生 类 对象。
- 如果 定义 的 类 将被 用作 基 类, 则应 将那 些 要在 派生 类 中 重新 定义 的 类 方法 声明 为 虚 的。
- 构造函数不能是虚的,析构应当是虚的,友元不是类成员,不能是虚的
- 如果派生类没有重新定义函数,将使用该函数的基类版本
- 重新定义将隐藏基类的方法
重新定义继承的方法并不是重载 如果在派生类.如果在派生类中重新定义函数,将不是使用相同的函数特征标覆盖基类声明,而是隐藏同名的基类方法,不管参数特征标如何.
有以下经验规则:
- 第一, 如果 重新 定义 继承 的 方法, 应 确保 与 原来 的 原型 完全 相同, 但如 果 返回类型 是 基类引用或指针, 则可以 修改为指向 派生类 的引用或 指针( 这种例外是新出现的)。 这种 特性 被称为 返回 类型 协 变, 因为允许返回 类型 随 类 类型 的 变化 而 变化:
- 第二,如果基类声明被重载了 则应在派生类中重新定义所有的基类版本
对于外部世界来说, 保护成员的行为与私有成员 相似; 但对于派生类 来说, 保护成员 的行为与公有成员相似。
抽象基类 纯虚函数在原型中使用 = 0 指出类是一 个抽象基 类, 在类中可以不定义该函数。



