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 |
|---|---|---|---|
| public | public | protected | 不可访问 |
| protected | protected | protected | 不可访问 |
| private | private | private | 不可访问 |
最佳实践
- 优先使用组合而非继承
- 基类析构函数声明为virtual
- 使用override关键字明确意图
- 谨慎使用多重继承
- 遵循里氏替换原则
继承为构建复杂的类层次结构提供了基础,是实现多态和设计模式的重要工具。