C++ 中的多重继承
C++ 中的多重继承功能允许一个类从多个基类继承,这意味着派生类可以有多个父类,并从所有基类继承属性和行为。
实现多重继承
要实现多重继承,需要在派生类中指定多个基类,并使用逗号分隔的列表声明。
语法
C++ 中多重继承的语法为:-
class Base1 {
// 基类 1 的成员
};
class Base2 {
// 基类 2 的成员
};
class Derived : public Base1, public Base2 {
// 派生类的成员
};
多重继承框图
请参阅下面的框图,演示多重继承 -
根据上图,"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() 方法。
主函数
- 现在这里,创建名为 myVehicle 的 DualModeVehicle。
- 其中调用了 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的节目
Base2::show(); // 明确调用Base2的节目
}
};
int main() {
Derived obj;
obj.show(); // 调用 Derived show() 方法,解决歧义
return 0;
}
输出
Base1 show Base2 show
在 int main() 函数体中,我们调用了 Deriveds 的 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
通过使用虚拟继承,我们可以避免"钻石难题",从而确保派生类层次结构中只存在一个基类实例。
使用多重继承的好处
- 代码可重用性,因为它允许开发人员使用现有类来创建具有组合功能的新类。
- 它更准确地模拟现实世界中的实体,其中一个派生类可能具有多个基类的特征。
- 它支持更灵活、更模块化的设计。

