Skip to content

C++ 继承

概述

继承是面向对象编程的核心特性之一,允许从现有类创建新类。派生类继承基类的属性和方法,并可以添加新功能或重写现有功能。这实现了代码重用和层次化设计。

🌳 基础继承

单继承

cpp
#include <iostream>
#include <string>

// 基类
class Animal {
protected:
    std::string name_;
    int age_;
    
public:
    Animal(const std::string& name, int age) : name_(name), age_(age) {
        std::cout << "Animal构造: " << name_ << std::endl;
    }
    
    virtual ~Animal() {
        std::cout << "Animal析构: " << name_ << std::endl;
    }
    
    virtual void makeSound() const {
        std::cout << name_ << " 发出声音" << std::endl;
    }
    
    void eat() const {
        std::cout << name_ << " 正在吃东西" << std::endl;
    }
    
    std::string getName() const { return name_; }
    int getAge() const { return age_; }
};

// 派生类
class Dog : public Animal {
private:
    std::string breed_;
    
public:
    Dog(const std::string& name, int age, const std::string& breed)
        : Animal(name, age), breed_(breed) {
        std::cout << "Dog构造: " << name_ << std::endl;
    }
    
    ~Dog() {
        std::cout << "Dog析构: " << name_ << std::endl;
    }
    
    // 重写基类方法
    void makeSound() const override {
        std::cout << name_ << " 汪汪叫" << std::endl;
    }
    
    // 新增方法
    void wagTail() const {
        std::cout << name_ << " 摇尾巴" << std::endl;
    }
    
    std::string getBreed() const { return breed_; }
};

int main() {
    std::cout << "=== 基础继承 ===" << std::endl;
    
    Dog myDog("旺财", 3, "金毛");
    
    // 继承的方法
    myDog.eat();
    std::cout << "年龄: " << myDog.getAge() << std::endl;
    
    // 重写的方法
    myDog.makeSound();
    
    // 新增的方法
    myDog.wagTail();
    std::cout << "品种: " << myDog.getBreed() << std::endl;
    
    return 0;
}

访问控制和继承

cpp
#include <iostream>

class Base {
private:
    int private_member_ = 10;
protected:
    int protected_member_ = 20;
public:
    int public_member_ = 30;
    
    void showMembers() const {
        std::cout << "私有: " << private_member_ 
                  << ", 保护: " << protected_member_ 
                  << ", 公有: " << public_member_ << std::endl;
    }
};

// public继承
class PublicDerived : public Base {
public:
    void accessMembers() {
        // private_member_ = 100;    // 错误!不能访问私有成员
        protected_member_ = 200;     // OK: 可以访问保护成员
        public_member_ = 300;        // OK: 可以访问公有成员
    }
};

// protected继承
class ProtectedDerived : protected Base {
public:
    void accessMembers() {
        protected_member_ = 400;     // OK
        public_member_ = 500;        // OK,但变成protected
    }
};

// private继承
class PrivateDerived : private Base {
public:
    void accessMembers() {
        protected_member_ = 600;     // OK
        public_member_ = 700;        // OK,但变成private
    }
    
    // 选择性公开基类接口
    using Base::showMembers;
};

int main() {
    std::cout << "=== 继承访问控制 ===" << std::endl;
    
    PublicDerived pub;
    pub.accessMembers();
    pub.showMembers();              // OK: public继承保持public
    pub.public_member_ = 1000;      // OK: 外部可访问
    
    ProtectedDerived prot;
    prot.accessMembers();
    // prot.showMembers();          // 错误!变成protected
    
    PrivateDerived priv;
    priv.accessMembers();
    priv.showMembers();             // OK: 使用using声明公开
    // priv.public_member_ = 2000;  // 错误!变成private
    
    return 0;
}

🔄 虚函数和多态

虚函数机制

cpp
#include <iostream>
#include <vector>
#include <memory>

class Shape {
protected:
    std::string name_;
    
public:
    Shape(const std::string& name) : name_(name) {}
    
    virtual ~Shape() = default;
    
    // 纯虚函数
    virtual double getArea() const = 0;
    virtual double getPerimeter() const = 0;
    
    // 虚函数
    virtual void display() const {
        std::cout << name_ << " - 面积: " << getArea() 
                  << ", 周长: " << getPerimeter() << std::endl;
    }
    
    std::string getName() const { return name_; }
};

class Rectangle : public Shape {
private:
    double width_, height_;
    
public:
    Rectangle(double width, double height) 
        : Shape("矩形"), width_(width), height_(height) {}
    
    double getArea() const override {
        return width_ * height_;
    }
    
    double getPerimeter() const override {
        return 2 * (width_ + height_);
    }
};

class Circle : public Shape {
private:
    double radius_;
    static constexpr double PI = 3.14159;
    
public:
    Circle(double radius) : Shape("圆形"), radius_(radius) {}
    
    double getArea() const override {
        return PI * radius_ * radius_;
    }
    
    double getPerimeter() const override {
        return 2 * PI * radius_;
    }
    
    void display() const override {
        std::cout << name_ << " (半径: " << radius_ << ") - 面积: " 
                  << getArea() << ", 周长: " << getPerimeter() << std::endl;
    }
};

int main() {
    std::cout << "=== 虚函数和多态 ===" << std::endl;
    
    // 多态容器
    std::vector<std::unique_ptr<Shape>> shapes;
    shapes.push_back(std::make_unique<Rectangle>(5, 3));
    shapes.push_back(std::make_unique<Circle>(4));
    shapes.push_back(std::make_unique<Rectangle>(2, 7));
    
    // 多态调用
    for (const auto& shape : shapes) {
        shape->display();  // 动态绑定
    }
    
    return 0;
}

🌐 多重继承

多重继承基础

cpp
#include <iostream>

class Flyable {
public:
    virtual ~Flyable() = default;
    virtual void fly() const = 0;
};

class Swimmable {
public:
    virtual ~Swimmable() = default;
    virtual void swim() const = 0;
};

class Animal {
protected:
    std::string name_;
    
public:
    Animal(const std::string& name) : name_(name) {}
    virtual ~Animal() = default;
    
    virtual void eat() const {
        std::cout << name_ << " 正在吃东西" << std::endl;
    }
    
    std::string getName() const { return name_; }
};

// 多重继承
class Duck : public Animal, public Flyable, public Swimmable {
public:
    Duck(const std::string& name) : Animal(name) {}
    
    void fly() const override {
        std::cout << name_ << " 在天空飞翔" << std::endl;
    }
    
    void swim() const override {
        std::cout << name_ << " 在水中游泳" << std::endl;
    }
    
    void eat() const override {
        std::cout << name_ << " 吃鱼和水草" << std::endl;
    }
};

int main() {
    std::cout << "=== 多重继承 ===" << std::endl;
    
    Duck duck("唐老鸭");
    
    duck.eat();
    duck.fly();
    duck.swim();
    
    // 类型转换
    Flyable* flyable = &duck;
    flyable->fly();
    
    Swimmable* swimmable = &duck;
    swimmable->swim();
    
    return 0;
}

虚继承解决菱形继承

cpp
#include <iostream>

class Animal {
protected:
    std::string species_;
    
public:
    Animal(const std::string& species) : species_(species) {
        std::cout << "Animal构造: " << species_ << std::endl;
    }
    
    virtual ~Animal() {
        std::cout << "Animal析构: " << species_ << std::endl;
    }
    
    std::string getSpecies() const { return species_; }
};

// 虚继承
class Mammal : public virtual Animal {
public:
    Mammal(const std::string& species) : Animal(species) {
        std::cout << "Mammal构造" << std::endl;
    }
    
    ~Mammal() {
        std::cout << "Mammal析构" << std::endl;
    }
    
    void breathe() const {
        std::cout << species_ << " 用肺呼吸" << std::endl;
    }
};

class WingedAnimal : public virtual Animal {
public:
    WingedAnimal(const std::string& species) : Animal(species) {
        std::cout << "WingedAnimal构造" << std::endl;
    }
    
    ~WingedAnimal() {
        std::cout << "WingedAnimal析构" << std::endl;
    }
    
    void flap() const {
        std::cout << species_ << " 拍打翅膀" << std::endl;
    }
};

// 菱形继承
class Bat : public Mammal, public WingedAnimal {
public:
    Bat() : Animal("蝙蝠"), Mammal("蝙蝠"), WingedAnimal("蝙蝠") {
        std::cout << "Bat构造" << std::endl;
    }
    
    ~Bat() {
        std::cout << "Bat析构" << std::endl;
    }
    
    void echolocate() const {
        std::cout << species_ << " 使用回声定位" << std::endl;
    }
};

int main() {
    std::cout << "=== 虚继承 ===" << std::endl;
    
    {
        Bat bat;
        std::cout << "物种: " << bat.getSpecies() << std::endl;
        bat.breathe();
        bat.flap();
        bat.echolocate();
    }
    
    return 0;
}

📋 继承最佳实践

设计模式应用

cpp
#include <iostream>
#include <vector>
#include <memory>

// 策略模式
class SortStrategy {
public:
    virtual ~SortStrategy() = default;
    virtual void sort(std::vector<int>& data) const = 0;
    virtual std::string getName() const = 0;
};

class BubbleSort : public SortStrategy {
public:
    void sort(std::vector<int>& data) const override {
        // 简化的冒泡排序
        for (size_t i = 0; i < data.size(); ++i) {
            for (size_t j = 0; j < data.size() - 1; ++j) {
                if (data[j] > data[j + 1]) {
                    std::swap(data[j], data[j + 1]);
                }
            }
        }
    }
    
    std::string getName() const override { return "冒泡排序"; }
};

class QuickSort : public SortStrategy {
public:
    void sort(std::vector<int>& data) const override {
        // 使用标准库快排
        std::sort(data.begin(), data.end());
    }
    
    std::string getName() const override { return "快速排序"; }
};

class SortContext {
private:
    std::unique_ptr<SortStrategy> strategy_;
    
public:
    void setStrategy(std::unique_ptr<SortStrategy> strategy) {
        strategy_ = std::move(strategy);
    }
    
    void performSort(std::vector<int>& data) {
        if (strategy_) {
            std::cout << "使用" << strategy_->getName() << "排序" << std::endl;
            strategy_->sort(data);
        }
    }
};

int main() {
    std::cout << "=== 继承设计模式 ===" << std::endl;
    
    std::vector<int> data1 = {64, 34, 25, 12, 22, 11, 90};
    std::vector<int> data2 = data1;
    
    SortContext context;
    
    // 使用冒泡排序
    context.setStrategy(std::make_unique<BubbleSort>());
    context.performSort(data1);
    
    std::cout << "结果: ";
    for (int n : data1) std::cout << n << " ";
    std::cout << std::endl;
    
    // 切换到快速排序
    context.setStrategy(std::make_unique<QuickSort>());
    context.performSort(data2);
    
    std::cout << "结果: ";
    for (int n : data2) std::cout << n << " ";
    std::cout << std::endl;
    
    return 0;
}

总结

继承是C++面向对象编程的重要支柱,提供了代码重用和层次化设计的能力:

核心概念

  • 单继承:一个派生类继承一个基类
  • 多重继承:一个派生类继承多个基类
  • 虚继承:解决菱形继承问题
  • 虚函数:实现运行时多态

继承类型

继承方式基类public基类protected基类private
publicpublicprotected不可访问
protectedprotectedprotected不可访问
privateprivateprivate不可访问

最佳实践

  • 优先使用组合而非继承
  • 基类析构函数声明为virtual
  • 使用override关键字明确意图
  • 谨慎使用多重继承
  • 遵循里氏替换原则

继承为构建复杂的类层次结构提供了基础,是实现多态和设计模式的重要工具。

本站内容仅供学习和研究使用。