C++继承技巧大公开:用好继承,让你的类功能强大10倍
发布时间: 2024-12-09 17:33:28 阅读量: 13 订阅数: 18
springboot167基于springboot的医院后台管理系统的设计与实现.zip
![C++面向对象编程的核心概念](https://img-blog.csdnimg.cn/direct/2f72a07a3aee4679b3f5fe0489ab3449.png)
# 1. C++继承的基本概念和作用
## C++继承的基本概念
继承是面向对象编程(OOP)的一个核心概念,它允许程序员创建一个新类,称为派生类(子类),该类继承另一个类,称为基类(父类)的属性和方法。继承表示了一种“是一个”(is-a)的关系。例如,在现实世界中,汽车是一个交通工具,因此汽车类可以继承交通工具类的特性。
在C++中,继承可以通过冒号(:)实现,后跟继承类型和基类名称。例如:
```cpp
class BaseClass {
// 基类成员
};
class DerivedClass : public BaseClass {
// 派生类成员
};
```
在这个例子中,`DerivedClass` 继承了 `BaseClass`,这意味着所有 `BaseClass` 的公有成员在 `DerivedClass` 中也都是公有的。
## C++继承的作用
继承的作用主要体现在以下几个方面:
1. **代码复用**:通过继承,派生类可以重用基类的代码,避免重复编写相同的代码。
2. **扩展性**:继承使得系统更易于扩展。当需要新的功能时,可以创建新的派生类,而不需要修改现有的类。
3. **实现多态**:通过继承,可以在基类中定义接口,并在派生类中提供具体实现,从而实现多态。
举个简单的例子,如果有一个基类 `Animal`,定义了 `speak` 函数的接口,而 `Dog` 和 `Cat` 类继承自 `Animal` 并提供各自的 `speak` 实现,这样就实现了多态。
```cpp
class Animal {
public:
virtual void speak() = 0; // 纯虚函数,定义接口
};
class Dog : public Animal {
public:
void speak() override {
std::cout << "Bark!" << std::endl;
}
};
class Cat : public Animal {
public:
void speak() override {
std::cout << "Meow!" << std::endl;
}
};
```
通过这个例子,我们可以看到继承如何通过定义一个接口在派生类中实现不同的行为,这是实现多态的关键。下一章节将深入探讨C++中的不同继承类型及其实现方式。
# 2. C++继承类型及其实现方式
### 2.1 单继承和多继承
#### 2.1.1 单继承的定义和应用场景
单继承是面向对象编程中一种基础的继承方式,它指的是一个类仅直接继承自另一个类。这种继承关系简单明了,易于理解和维护,是初学者学习继承时首先接触的概念。
```cpp
class Base {
public:
void baseFunction() { /*...*/ }
};
class Derived : public Base {
public:
void derivedFunction() { /*...*/ }
};
```
在这个例子中,`Derived` 类单继承自 `Base` 类。这意味着 `Derived` 类对象可以使用 `Base` 类的所有公有成员函数和变量。单继承的优势在于它保证了程序的清晰结构,避免了复杂的菱形继承问题。
单继承通常用于实现“是一个”的关系,比如在汽车游戏中,一个特定类型的汽车(如`SportsCar`)可以继承自`Car`类,因为`SportsCar`“是一个”`Car`。
#### 2.1.2 多继承的定义和应用场景
多继承则是指一个类同时继承自两个或两个以上的类。这为程序设计提供了更大的灵活性,但也引入了复杂性,比如二义性问题。
```cpp
class Interface1 { /*...*/ };
class Interface2 { /*...*/ };
class Implementation : public Interface1, public Interface2 {
// 类成员声明
};
```
在多继承中,派生类`Implementation`继承了`Interface1`和`Interface2`两个接口的所有成员。在C++中,多继承可以用来实现“一个类同时是一个”的关系,例如,`FlyingCar`既可以继承自`Car`也可以继承自`Aircraft`。
然而,多继承在处理继承的成员时可能会产生二义性,例如当两个基类有同名函数时,派生类需要明确指出使用哪一个基类的函数,或者在派生类中重写同名函数。
### 2.2 公有继承、私有继承和保护继承
#### 2.2.1 公有继承的特点和应用
公有继承是C++中继承方式的一种,它也是默认的继承方式。在公有继承中,基类的公有成员和保护成员在派生类中保持其原有的属性,而基类的私有成员在派生类中是不可访问的,但可以通过基类的公有和保护成员函数来访问。
```cpp
class Base {
protected:
int baseValue;
public:
void setBaseValue(int value) { baseValue = value; }
int getBaseValue() { return baseValue; }
};
class Derived : public Base {
public:
void derivedFunction() {
setBaseValue(10); // 基类成员函数调用
// baseValue = 10; // 错误:baseValue是保护成员,在Derived中不可直接访问
}
};
```
在公有继承中,基类的`public`和`protected`成员在派生类中保持不变,而`private`成员在派生类中不可访问。公有继承通常用于实现“是一个”的关系,例如,`Employee`类公有继承自`Person`类。
#### 2.2.2 私有继承和保护继承的异同和选择
私有继承和保护继承是C++中非公有继承的两种方式,它们在派生类中改变了基类成员的访问属性。私有继承使得基类的所有公有成员和保护成员都变为私有成员,而保护继承则将这些成员变为保护成员。
```cpp
class Base {
public:
int baseValue;
};
class Derived : private Base {
// baseValue在Derived中是私有成员
};
class Derived2 : protected Base {
// baseValue在Derived2中是保护成员
};
```
私有继承和保护继承的选择取决于你的设计需求。如果派生类不想让基类接口在类外被直接使用,而是想在内部封装,可能会选择私有继承。如果需要在派生类和其派生类之间共享基类接口,可能会选择保护继承。
私有继承和保护继承在派生类中隐藏了基类的实现细节,增强了封装性,但也限制了访问,使得继承的灵活性降低。
### 2.3 虚继承的原理和应用
#### 2.3.1 虚继承的定义和作用
虚继承是C++特有的继承方式,它用于解决多重继承中菱形继承问题(也称为钻石问题),即两个派生类都继承自同一个基类,然后又有一个类同时继承这两个派生类。
```cpp
class Base { /* ... */ };
class Left : virtual public Base { /* ... */ };
class Right : virtual public Base { /* ... */ };
class Subclass : public Left, public Right { /* ... */ };
```
在虚继承中,基类通过`virtual`关键字标识为虚继承,这保证了派生类共享基类的一份实例,无论继承层级有多深。
虚继承的主要作用是:
1. 避免了在多继承中基类成员被重复继承的问题。
2. 确保了基类的构造函数只被调用一次。
#### 2.3.2 虚继承和非虚继承的区别
虚继承和非虚继承在实现上有显著的不同。非虚继承中,每个派生类都会继承基类的一份独立副本,而在虚继承中,基类的实例共享,通过一个被称为“虚基类
0
0