跳转到内容

C++ 继承类型

来自代码酷

C++继承类型[编辑 | 编辑源代码]

继承是面向对象编程(OOP)的核心概念之一,允许一个类(派生类)基于另一个类(基类)构建,从而复用代码并建立层次关系。C++支持多种继承类型,每种类型定义了基类和派生类之间的不同访问权限和数据共享方式。本文将详细介绍C++中的继承类型及其应用。

继承的基本语法[编辑 | 编辑源代码]

在C++中,继承通过以下语法实现:

class BaseClass {
    // 基类成员
};

class DerivedClass : access-specifier BaseClass {
    // 派生类成员
};

其中,`access-specifier`可以是`public`、`protected`或`private`,决定了基类成员在派生类中的访问权限。

C++的三种继承类型[编辑 | 编辑源代码]

C++支持三种继承类型,分别对应不同的访问控制级别:

1. 公有继承(public inheritance)[编辑 | 编辑源代码]

公有继承是最常用的继承方式,它保持基类成员的访问权限不变:

  • 基类的`public`成员在派生类中仍为`public`。
  • 基类的`protected`成员在派生类中仍为`protected`。
  • 基类的`private`成员不可直接访问(仅通过基类的公有或保护方法访问)。

示例代码[编辑 | 编辑源代码]

#include <iostream>
using namespace std;

class Animal {
public:
    void eat() { cout << "Eating..." << endl; }
protected:
    void breathe() { cout << "Breathing..." << endl; }
private:
    void sleep() { cout << "Sleeping..." << endl; }
};

class Dog : public Animal {
public:
    void bark() { 
        eat();       // 可访问(public)
        breathe();   // 可访问(protected)
        // sleep();  // 错误:不可访问(private)
    }
};

int main() {
    Dog myDog;
    myDog.eat();    // 输出:Eating...
    myDog.bark();
    // myDog.breathe(); // 错误:不可访问(protected)
}

2. 保护继承(protected inheritance)[编辑 | 编辑源代码]

保护继承将基类的`public`和`protected`成员都变为派生类的`protected`成员:

  • 基类的`public`和`protected`成员在派生类中变为`protected`。
  • 基类的`private`成员仍不可直接访问。

示例代码[编辑 | 编辑源代码]

class Animal {
public:
    void eat() { cout << "Eating..." << endl; }
protected:
    void breathe() { cout << "Breathing..." << endl; }
};

class Dog : protected Animal {
public:
    void bark() {
        eat();     // 可访问(现在为protected)
        breathe(); // 可访问(protected)
    }
};

int main() {
    Dog myDog;
    // myDog.eat(); // 错误:现在为protected,外部不可访问
    myDog.bark();
}

3. 私有继承(private inheritance)[编辑 | 编辑源代码]

私有继承将基类的所有`public`和`protected`成员都变为派生类的`private`成员:

  • 基类的`public`和`protected`成员在派生类中变为`private`。
  • 基类的`private`成员仍不可直接访问。

示例代码[编辑 | 编辑源代码]

class Animal {
public:
    void eat() { cout << "Eating..." << endl; }
protected:
    void breathe() { cout << "Breathing..." << endl; }
};

class Dog : private Animal {
public:
    void bark() {
        eat();     // 可访问(现在为private)
        breathe();  // 可访问(现在为private)
    }
};

int main() {
    Dog myDog;
    // myDog.eat(); // 错误:现在为private,外部不可访问
    myDog.bark();
}

继承类型对比表[编辑 | 编辑源代码]

继承类型对成员访问权限的影响
继承类型 基类public成员 基类protected成员 基类private成员
public 派生类public 派生类protected 不可访问
protected 派生类protected 派生类protected 不可访问
private 派生类private 派生类private 不可访问

多重继承[编辑 | 编辑源代码]

C++支持多重继承,即一个派生类可以从多个基类继承。语法如下:

class Derived : public Base1, protected Base2, private Base3 {
    // 类定义
};

示例代码[编辑 | 编辑源代码]

#include <iostream>
using namespace std;

class LandAnimal {
public:
    void walk() { cout << "Walking..." << endl; }
};

class WaterAnimal {
public:
    void swim() { cout << "Swimming..." << endl; }
};

class Amphibian : public LandAnimal, public WaterAnimal {
public:
    void live() {
        walk();
        swim();
    }
};

int main() {
    Amphibian frog;
    frog.live();  // 输出:Walking... Swimming...
}

实际应用案例[编辑 | 编辑源代码]

图形处理系统是继承的典型应用场景。考虑一个图形系统,基类`Shape`定义通用属性和方法,派生类如`Circle`、`Rectangle`等实现特定功能:

class Shape {
protected:
    double x, y;
public:
    Shape(double x, double y) : x(x), y(y) {}
    virtual double area() const = 0;  // 纯虚函数
};

class Circle : public Shape {
    double radius;
public:
    Circle(double x, double y, double r) : Shape(x,y), radius(r) {}
    double area() const override { return 3.14159 * radius * radius; }
};

class Rectangle : public Shape {
    double width, height;
public:
    Rectangle(double x, double y, double w, double h) 
        : Shape(x,y), width(w), height(h) {}
    double area() const override { return width * height; }
};

继承关系图[编辑 | 编辑源代码]

classDiagram class Shape { <<abstract>> +double x +double y +Shape(double, double) +area() double* } class Circle { +double radius +Circle(double, double, double) +area() double } class Rectangle { +double width +double height +Rectangle(double, double, double, double) +area() double } Shape <|-- Circle Shape <|-- Rectangle

继承中的注意事项[编辑 | 编辑源代码]

1. 菱形继承问题:当多个基类继承自同一个祖先类时,可能导致数据冗余和访问歧义。C++通过虚继承解决:

   class A {};
   class B : virtual public A {};
   class C : virtual public A {};
   class D : public B, public C {};

2. 构造函数调用顺序:基类构造函数先于派生类构造函数调用,析构函数顺序相反。

3. 访问控制:即使使用公有继承,基类的`private`成员仍不可直接访问。

总结[编辑 | 编辑源代码]

C++的继承机制提供了强大的代码复用和组织能力。理解不同继承类型的区别对设计健壮的类层次结构至关重要:

  • 公有继承用于"是一个"的关系(is-a relationship)
  • 保护继承和私有继承用于"实现为"的关系(implemented-in-terms-of)
  • 多重继承需谨慎使用,避免复杂性

通过合理应用继承,可以创建灵活、可维护的面向对象系统。