C++ 中的继承是面向对象编程(OOP)的一部分,是用于创建新的类(派生类)的机制,新类可以从现有的类(基类或父类)中继承属性和方法。这种机制使得代码可以重用,并且能够建立一个类的层次结构,以实现多态性和代码的扩展性。下面详细介绍 C++ 中继承的关键概念:
1. 基本概念
- 基类(Base Class): 也称为父类或超类,是其他类可以继承的类。
- 派生类(Derived Class): 也称为子类,是从基类继承而来的类。
在 C++ 中,继承的语法如下:
class 基类 {
// 基类的成员
};
class 派生类 : 访问控制 基类 {
// 派生类的成员
};
其中,访问控制
可以是 public
、protected
或 private
,决定了派生类如何继承基类的成员。
2. 继承类型
-
公有继承(public inheritance): 基类的公有成员和保护成员在派生类中保持其访问权限,而私有成员在派生类中不可访问。
class Derived : public Base { // 基类的公有和保护成员在派生类中保持原样 };
保护继承(protected inheritance): 基类的公有成员和保护成员在派生类中都变成保护成员,而私有成员在派生类中不可访问。
class Derived : protected Base { // 基类的公有和保护成员在派生类中变成保护成员 };
私有继承(private inheritance): 基类的所有成员在派生类中都变成私有成员。
class Derived : private Base { // 基类的所有成员在派生类中变成私有成员 };
3. 构造函数和析构函数
在继承过程中,基类的构造函数和析构函数在派生类对象创建和销毁时分别会被调用:
- 构造函数调用顺序: 先调用基类的构造函数,然后调用派生类的构造函数。
- 析构函数调用顺序: 先调用派生类的析构函数,然后调用基类的析构函数。
4. 虚函数和多态性
虚函数使得基类和派生类可以有不同的实现方式,并且在运行时决定调用哪个版本的函数。这是实现多态性的关键。
class Base {
public:
virtual void display() {
std::cout << "Base display" << std::endl;
}
};
class Derived : public Base {
public:
void display() override {
std::cout << "Derived display" << std::endl;
}
};
在上述代码中,display
是一个虚函数。即使通过基类指针调用 display
方法,实际调用的是派生类的 display
方法。
5. 重载和隐藏
- 重载(Overriding): 派生类可以重新定义基类的虚函数。
- 隐藏(Hiding): 如果派生类定义了一个与基类同名的非虚函数,则基类的函数在派生类中被隐藏。
6. 多重继承
C++ 支持一个类从多个基类继承,称为多重继承。
class Base1 {
// 基类1的成员
};
class Base2 {
// 基类2的成员
};
class Derived : public Base1, public Base2 {
// 派生类同时继承自Base1和Base2
};
多重继承需要注意解决命名冲突和菱形继承(diamond problem)。
7. 菱形继承
当一个派生类从两个基类继承,而这两个基类又有一个共同的基类时,就会发生菱形继承问题。
class Grandparent {
// 祖父类的成员
};
class Parent1 : public Grandparent {
// 父类1的成员
};
class Parent2 : public Grandparent {
// 父类2的成员
};
class Child : public Parent1, public Parent2 {
// 子类继承自Parent1和Parent2
};
为了解决菱形继承中的重复继承问题,C++ 引入了虚继承(virtual inheritance)。
class Parent1 : virtual public Grandparent {
// 虚继承祖父类
};
class Parent2 : virtual public Grandparent {
// 虚继承祖父类
};
例子
以下是一个简单的继承例子:
#include <iostream>
using namespace std;
// 基类
class Animal {
public:
void eat() {
cout << "I can eat!" << endl;
}
void sleep() {
cout << "I can sleep!" << endl;
}
};
// 派生类
class Dog : public Animal {
public:
void bark() {
cout << "I can bark! Woof woof!!" << endl;
}
};
int main() {
Dog myDog;
myDog.eat(); // 调用基类的方法
myDog.sleep(); // 调用基类的方法
myDog.bark(); // 调用派生类的方法
return 0;
}
在这个例子中,Dog
类继承了 Animal
类,所以 Dog
类对象 myDog
可以调用 Animal
类的 eat
和 sleep
方法。
总结
C++ 中的继承是创建代码模块化和重用的强大工具,它允许在不同类之间共享和扩展行为。理解继承的各种机制和语法对于掌握 C++ 的面向对象编程至关重要。