主页
  • 主页
  • 分类
  • 热文
  • 教程
  • 面试
  • 标签
C++

C++ 基础

C++ 主页
C++ 概述
C++ 环境
C++ 基本语法
C++ 注释
C++ 数据类型
C++ Hello, World
C++ 省略命名空间
C++ 数值类型
C++ 字符类型
C++ 布尔类型
C++ 变量
C++ 作用域
C++ 多个变量
C++ 输入输出基础
C++ 常量/文字
C++ 修饰符类型
C++ 存储类别
C++ 操作符
C++ 决策结构
C++ 循环结构
C++ foreach 循环
C++ 数字
C++ 数组
C++ 指针
C++ 枚举类型
C++ 引用变量
C++ 日期与时间
C++ 结构体
C++ 联合类型

C++ 字符串

C++ 字符串
C++ 字符串长度
C++ 字符串连接

C++ 函数

C++ 函数
C++ 多参数函数
C++ 递归
C++ return 语句
C++ 函数重载
C++ 函数重写

C++ 面向对象

C++ 面向对象
C++ 类和对象
C++ 多重继承
C++ 多层次继承
C++ 继承
C++ 重载
C++ 多态性
C++ 抽象
C++ 封装
C++ 接口

C++ 高级

C++ 文件和流
C++ 异常处理
C++ 动态内存
C++ 命名空间
C++ 模板
C++ 预处理器
C++ 信号量
C++ 多线程
C++ Web 编程
C++ 高级概念

基础

C++ 主页
C++ 概述
C++ 环境
C++ 基本语法
C++ 注释
C++ 数据类型
C++ Hello, World
C++ 省略命名空间
C++ 数值类型
C++ 字符类型
C++ 布尔类型
C++ 变量
C++ 作用域
C++ 多个变量
C++ 输入输出基础
C++ 常量/文字
C++ 修饰符类型
C++ 存储类别
C++ 操作符
C++ 决策结构
C++ 循环结构
C++ foreach 循环
C++ 数字
C++ 数组
C++ 指针
C++ 枚举类型
C++ 引用变量
C++ 日期与时间
C++ 结构体
C++ 联合类型

字符串

C++ 字符串
C++ 字符串长度
C++ 字符串连接

函数

C++ 函数
C++ 多参数函数
C++ 递归
C++ return 语句
C++ 函数重载
C++ 函数重写

面向对象

C++ 面向对象
C++ 类和对象
C++ 多重继承
C++ 多层次继承
C++ 继承
C++ 重载
C++ 多态性
C++ 抽象
C++ 封装
C++ 接口

高级

C++ 文件和流
C++ 异常处理
C++ 动态内存
C++ 命名空间
C++ 模板
C++ 预处理器
C++ 信号量
C++ 多线程
C++ Web 编程
C++ 高级概念

C++ 多重继承


上一章 下一章

多重继承是 C++ 中的一项特性,它允许一个类从多个基类继承,这意味着一个派生类可以有多个父类,并且可以从所有基类继承属性和行为。

实现多重继承

为了实现多重继承,你需要在派生类中指定多个基类,并使用逗号分隔的列表来声明它。

语法

多重继承在 C++ 中的语法如下:

class Base1 {
   // 基类 1 成员
};

class Base2 {
   // 基类 2 成员
};

class Derived : public Base1, public Base2 {
   // 派生类成员
};

多重继承的框图

参见下面的框图,展示多重继承:

C++ Multiple Inheritance

C++ 多重继承 根据上述框图,类 "Car" 和 "Boat" 是基类,并且它们为了实现多重继承而派生到 "DualModeVehicle" 类。

多重继承示例

在下面的例子中,有两个基类 "Car" 和 "Boat",以及一个派生类 "DualModeVehicle"。这两个基类都被派生类继承。

#include <iostream>
using namespace std;

// 基类 1
class Car {
   public:
      void drive() {
         cout << "Driving on land" << endl;
      }
};

// 基类 2
class Boat {
   public:
      void sail() {
         cout << "Sailing on water" << endl;
      }
};

// 派生类
class DualModeVehicle: public Car, public Boat {
   public:
      void use() {
         drive(); // 调用 Car 中的 drive 函数
         sail();   // 调用 Boat 中的 sail 函数
      }
};

int main() {
   DualModeVehicle myVehicle;
   myVehicle.use(); // 展示两种功能
   return 0;
}

输出

Driving on land
Sailing on water

解释

类 Car 是我们的第一个基类,拥有公共成员函数 drive();而类 Boat 是第二个基类,拥有公共成员函数 sail()。 现在有一个名为 DualModeVehicle 的派生类,它从 Car 和 Boat 继承,并使用多重继承来组合两个基类的功能。 其中有一个公共成员函数 use(),它调用了 Car 类中的 drive 方法和 Boat 类中的 sail 方法。 主函数 在这里,创建了一个 DualModeVehicle 的实例,名为 myVehicle。 myVehicle 的 use() 方法被调用,进而调用了 drive() 和 sail()。 返回 0 表示成功执行。

多重继承中的挑战

多重继承在 C++ 中允许一个类从多个基类继承,这提供了灵活性和可重用性。然而,它也带来了一些挑战,如下所述:

  • 歧义 - 当两个或更多基类有同名成员时会引起歧义。
  • 菱形问题 - 当一个类从两个都继承自共同基类的类继承时会产生菱形问题,这会导致由于基类的多个副本引起的歧义和冲突,最终被称为菱形问题。

多重继承中的歧义

如果两个或更多的基类有同名成员(函数或变量),编译器将无法决定使用哪一个,从而导致歧义。

这可以通过使用作用域解析来解决。

语法

class Base1 {
public:
   void show() { cout << "Base1 show" << endl; }
};

class Base2 {
   public:
      void show() { cout << "Base2 show" << endl; }
};

class Derived : public Base1, public Base2 {
   public:
      void show() {
         Base1::show(); // 明确调用 Base1 的 show
         Base2::show(); // 明确调用 Base2 的 show
      }
};

在多重继承中处理歧义

这里我们将演示如何使用显式的作用域解析来指定应该调用哪个基类的方法来处理多重继承中的歧义。

示例

让我们通过一个例子来考虑它

#include <iostream>
using namespace std;

class Base1 {
   public:
      void show() {
         cout << "Base1 show" << endl;
      }
};

class Base2 {
   public:
      void show() {
         cout << "Base2 show" << endl;
      }
};

class Derived : public Base1, public Base2 {
   public:
      void show() {
         // 歧义发生在这里,因为 Base1 和 Base2 都有一个 show() 方法
         Base1::show(); // 明确调用 Base1 的 show
         Base2::show(); // 明确调用 Base2 的 show
      }
};

int main() {
   Derived obj;
   obj.show();  // 调用 Derived 的 show() 方法,解决歧义
   return 0;
}

输出

Base1 show
Base2 show

在 int main() 的主体中,我们调用了 Derived 的 show() 方法,解决了歧义。

多重继承中的菱形问题

C++ 中的菱形问题发生在当一个类从两个都继承自共同基类的类继承时,这最终会在继承层次结构中产生歧义,因为派生类现在有两个共同基类的副本,从而导致冲突。

示例

#include <iostream>
using namespace std;

class Base {
   public:
      void show() {
         cout << "Base show" << endl;
      }
};

class Derived1 : public Base {};
class Derived2 : public Base {};

class Final : public Derived1, public Derived2 {};

int main() {
   Final obj;
   // obj.show(); // 这一行会导致歧义
   return 0;
}

多重继承中的菱形问题解决方案

解决 C++ 中菱形问题的主要方法是使用虚继承。

示例

#include <iostream>
using namespace std;

class Base {
   public:
      void show() {
         cout << "Base show" << endl;
      }
};

class Derived1 : virtual public Base {};  // 虚继承
class Derived2 : virtual public Base {};  // 虚继承

class Final : public Derived1, public Derived2 {};

int main() {
   Final obj;
   obj.show(); // 现在这行调用 Base 的 show() 没有歧义
   return 0;
}

输出

Base show

通过使用虚继承,我们可以避免菱形问题的挑战,这确保了在派生类层次结构中只有一个基类的实例。

使用多重继承的好处

  • 代码重用性 - 它允许开发人员使用现有类来创建具有组合功能的新类。
  • 更准确地建模现实世界实体 - 其中派生类可能具有多个基类的特征。
  • 使设计更加灵活和模块化。
上一章 下一章
阅读号二维码

关注阅读号

联系二维码

联系我们

© 2024 Yoagoa. All rights reserved.

粤ICP备18007391号

站点地图