继承是C++中面向对象编程的一个重要特性,它允许一个类(派生类)从另一个类(基类)继承属性和行为(即成员变量和成员函数)。通过继承,开发者可以重用已有代码,扩展类的功能,并实现多态性。本文将详细介绍C++中的继承,包括其基本概念、类型、实现方法和常见问题。
1. 继承的基本概念
在C++中,继承用于创建一个新类,使其拥有一个或多个已有类的属性和方法。基类提供了基本的接口和实现,而派生类则可以扩展或修改这些接口和实现。
示例
class Base {
public:
void display() {
std::cout << "Display Base class" << std::endl;
}
};
class Derived : public Base {
public:
void show() {
std::cout << "Show Derived class" << std::endl;
}
};
在上述例子中,Derived
类继承了 Base
类,并增加了一个新的方法 show
。
2. 继承的类型
C++支持三种类型的继承:公有继承、保护继承和私有继承。这三种继承方式决定了基类成员在派生类中的访问权限。
公有继承(public inheritance)
在公有继承中,基类的公有成员在派生类中保持公有,保护成员在派生类中保持保护,私有成员在派生类中不可访问。
class Base {
public:
int publicVar;
protected:
int protectedVar;
private:
int privateVar;
};
class Derived : public Base {
// publicVar 是 public
// protectedVar 是 protected
// privateVar 是不可访问的
};
保护继承(protected inheritance)
在保护继承中,基类的公有和保护成员在派生类中都变成保护成员。
class Derived : protected Base {
// publicVar 是 protected
// protectedVar 是 protected
// privateVar 是不可访问的
};
私有继承(private inheritance)
在私有继承中,基类的公有和保护成员在派生类中都变成私有成员。
class Derived : private Base {
// publicVar 是 private
// protectedVar 是 private
// privateVar 是不可访问的
};
3. 重写和重载
重写(Overriding)
重写是指在派生类中重新定义基类中的虚函数。通过重写,派生类可以提供特定的实现。重写必须使用 virtual
关键字。
class Base {
public:
virtual void display() {
std::cout << "Display Base class" << std::endl;
}
};
class Derived : public Base {
public:
void display() override {
std::cout << "Display Derived class" << std::endl;
}
};
重载(Overloading)
重载是指在同一个作用域中定义多个函数,它们具有相同的名称但参数列表不同。重载不涉及继承,是在同一个类中实现的。
class Example {
public:
void display() {
std::cout << "Display no parameters" << std::endl;
}
void display(int i) {
std::cout << "Display with int parameter: " << i << std::endl;
}
};
4. 多重继承
C++允许一个派生类继承多个基类,这种方式称为多重继承。多重继承可以引入更复杂的关系,但也可能带来潜在的歧义和复杂性。
class Base1 {
public:
void display() {
std::cout << "Display Base1 class" << std::endl;
}
};
class Base2 {
public:
void show() {
std::cout << "Show Base2 class" << std::endl;
}
};
class Derived : public Base1, public Base2 {
// Derived类同时继承Base1和Base2
};
菱形继承问题
菱形继承是多重继承中一个常见的问题,当一个类同时继承两个基类,而这两个基类又继承自同一个基类时,会出现菱形结构。
class Base {
public:
int var;
};
class Derived1 : public Base {};
class Derived2 : public Base {};
class Derived3 : public Derived1, public Derived2 {
// 继承链形成菱形结构
};
解决方法是使用虚继承(virtual inheritance),使得基类的实例在派生类中只保留一份。
class Base {
public:
int var;
};
class Derived1 : virtual public Base {};
class Derived2 : virtual public Base {};
class Derived3 : public Derived1, public Derived2 {
// 使用虚继承避免菱形继承问题
};
5. 抽象类和纯虚函数
抽象类是包含纯虚函数的类,不能实例化。纯虚函数是没有实现的函数,定义方式是在函数声明后加 = 0
。
class AbstractBase {
public:
virtual void display() = 0; // 纯虚函数
};
class ConcreteDerived : public AbstractBase {
public:
void display() override {
std::cout << "Concrete implementation" << std::endl;
}
};
分析说明表
概念 | 描述 |
---|---|
基类 | 提供基本接口和实现的类 |
派生类 | 继承自基类并扩展或修改其功能的类 |
公有继承 | 基类的公有和保护成员在派生类中分别保持公有和保护访问级别 |
保护继承 | 基类的公有和保护成员在派生类中都变成保护访问级别 |
私有继承 | 基类的公有和保护成员在派生类中都变成私有访问级别 |
重写 | 在派生类中重新定义基类的虚函数 |
重载 | 在同一个类中定义多个同名函数,但参数列表不同 |
多重继承 | 一个派生类继承多个基类 |
菱形继承 | 多重继承中一个类继承两个基类,而这两个基类又继承自同一个基类 |
抽象类 | 包含纯虚函数的类,不能实例化 |
纯虚函数 | 没有实现的函数,必须在派生类中实现 |
思维导图
C++继承
|
|-- 基本概念
| |-- 基类和派生类
|
|-- 继承类型
| |-- 公有继承
| |-- 保护继承
| |-- 私有继承
|
|-- 重写和重载
| |-- 重写
| |-- 重载
|
|-- 多重继承
| |-- 多重继承概念
| |-- 菱形继承问题
| |-- 虚继承解决
|
|-- 抽象类和纯虚函数
| |-- 抽象类
| |-- 纯虚函数
结论
通过继承,C++可以实现代码重用、扩展类的功能并支持多态性。理解继承的类型、重写与重载、多重继承及其相关问题,对于掌握C++面向对象编程至关重要。希望本文能为您的C++学习和开发提供实用的指导。