# 多继承基本语法

URL: https://caijiao.org/cpp/oop/multiple
Source: docs/cpp/oop/multiple.md
Description: 本节介绍 C++ 中的多继承基本语法，讲解如何在 C++ 中使用多继承，以及如何处理继承中的冲突和问题。

在 C++ 中，多继承是指一个类可以继承多个基类。这允许派生类同时拥有多个基类的属性和方法。虽然多继承提供了强大的功能，但也可能带来复杂性，特别是在处理多个基类中的相同成员时。

## 多继承的基本语法

在 C++ 中，通过在类声明中列出多个基类来实现多继承。各个基类用逗号隔开。

### 示例：多继承

```cpp
#include <iostream>
using namespace std;

class Animal {
public:
    void eat() {
        cout << "Eating..." << endl;
    }
};

class Bird {
public:
    void fly() {
        cout << "Flying..." << endl;
    }
};

class Sparrow : public Animal, public Bird {
public:
    void sing() {
        cout << "Singing..." << endl;
    }
};

int main() {
    Sparrow sparrow;
    sparrow.eat();  // 从 Animal 类继承
    sparrow.fly();  // 从 Bird 类继承
    sparrow.sing(); // 自己定义的功能

    return 0;
}
````

### 输出：

```
Eating...
Flying...
Singing...
```

在上面的示例中，`Sparrow` 类通过多继承继承了 `Animal` 和 `Bird` 类的功能。`Sparrow` 类可以访问两个基类的成员函数，并且还定义了自己的函数 `sing()`。

## 多继承中的问题

尽管多继承提供了灵活性，但它也会带来一些问题，最常见的问题是 **钻石问题**（Diamond Problem）。钻石问题发生在一个类继承自两个类，而这两个类又有一个共同的基类。

### 钻石问题

假设我们有如下的继承关系：

```cpp
class A {
public:
    void show() {
        cout << "Class A" << endl;
    }
};

class B : public A {
public:
    void show() {
        cout << "Class B" << endl;
    }
};

class C : public A {
public:
    void show() {
        cout << "Class C" << endl;
    }
};

class D : public B, public C {
    // D 从 B 和 C 继承了 show 方法
};
```

在这种情况下，`D` 类继承了 `B` 和 `C`，而 `B` 和 `C` 又都继承自 `A`。这就会导致 `D` 类同时继承了 `B` 和 `C` 中的 `show()` 方法，从而产生了冲突。

### 解决钻石问题：虚拟继承

为了避免这种冲突，C++ 引入了虚拟继承。虚拟继承保证了在多重继承中，某个基类只有一份实例，避免了重复继承。

### 虚拟继承示例

```cpp
class A {
public:
    void show() {
        cout << "Class A" << endl;
    }
};

class B : virtual public A {
public:
    void show() {
        cout << "Class B" << endl;
    }
};

class C : virtual public A {
public:
    void show() {
        cout << "Class C" << endl;
    }
};

class D : public B, public C {
    // 通过虚拟继承，D 只会有一个 A 类的实例
};

int main() {
    D d;
    d.show();  // 如果没有虚拟继承，会有冲突，若使用虚拟继承，输出的是最新重写的 show()
    return 0;
}
```

### 小结

* **多继承**：允许派生类继承多个基类，可以使得一个类拥有多个基类的功能。
* **钻石问题**：当多个派生类继承相同的基类时，可能会产生冲突，导致二义性。
* **虚拟继承**：通过 `virtual` 关键字可以解决钻石问题，确保基类只有一个实例。

多继承在 C++ 中是一个强大的特性，但在使用时需要注意避免继承冲突。通过合理设计，可以利用多继承带来的优势。
