继承允许派生类在基类已有成员与行为之上扩展或特化,形成 is-a 关系(例如狗是一种动物)。C++ 支持 public、protected、private 继承;public 继承时基类 public 成员在派生类中仍为 public。本节说明派生类定义、构造与析构顺序、名字隐藏与对象切片,为多态铺垫。

基本语法

#include <iostream>
#include <string>

class Animal {
public:
    std::string name;
    void speak() const { std::cout << name << " makes a sound\n"; }
};

class Dog : public Animal {
public:
    void speak() const { std::cout << name << " barks\n"; }
};

int main() {
    Dog d;
    d.name = "Rex";
    d.speak();
    return 0;
}

典型输出:Rex barks。Dog : public Animal 表示公有继承;派生类对象包含基类子对象,可访问基类 public / protected 成员(依继承方式而定)。

继承方式与访问

继承方式基类 public 成员在派生类中常见语义
publicpublic接口继承,is-a
protectedprotected实现继承,较少对外暴露
privateprivate实现细节复用,非 is-a 对外表达

构造与析构顺序

#include <iostream>

class Base {
public:
    Base() { std::cout << "Base 构造\n"; }
    ~Base() { std::cout << "Base 析构\n"; }
};

class Derived : public Base {
public:
    Derived() { std::cout << "Derived 构造\n"; }
    ~Derived() { std::cout << "Derived 析构\n"; }
};

int main() {
    Derived d;
    return 0;
}

典型输出顺序:Base 构造 → Derived 构造 → Derived 析构 → Base 析构。创建时先基类后派生;销毁时相反,见析构函数。

派生类构造函数与基类

若基类无默认构造,派生类须在初始化列表中显式调用基类构造函数:

class Base {
public:
    explicit Base(int x) : x_(x) {}
private:
    int x_;
};

class Derived : public Base {
public:
    Derived(int x, int y) : Base(x), y_(y) {}
private:
    int y_;
};

名字隐藏

派生类声明与基类同名的成员函数会隐藏基类所有同名重载,而非自动形成覆盖。若要多态覆盖须使用 virtual 与 override,见多态与虚函数。若仅需引入基类重载,可写:

using Animal::speak;

对象切片(slicing)

将派生类对象按值赋给基类对象时,派生部分被截断,只保留基类子对象:

Dog d;
Animal a = d;   // 切片:a 仅是 Animal 部分

需要多态行为时应使用基类指针或引用,或 std::unique_ptr<Base> 指向派生对象。

多重继承(入门)

C++ 允许从多个基类继承;菱形继承与虚基类属进阶主题。设计时优先组合(has-a)而非过深继承树,与封装原则一致。

本节说明了 public 继承与构造顺序。下一节介绍多态与虚函数:动态绑定与 override。