【人工智能教程】,前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。
点击跳转到网站:【人工智能教程】
文章目录
- 一、多态
- 1. 虚函数(Virtual Functions)
- 2. 抽象基类(Abstract Base Classes, ABCs)
- 二、多态应用场景
- 1. 图形绘制系统
- 2. 案例代码
- 3. 解释
- 三、虚函数、纯虚函数
- 1. 虚函数(Virtual Functions)
- 2. 纯虚函数(Pure Virtual Functions)
- 四、相关链接
一、多态
C++中的多态性(Polymorphism)是一种面向对象编程的特性,它允许我们通过基类指针或引用调用派生类的方法。多态性主要分为两种:编译时多态(静态多态)和运行时多态(动态多态)。在C++中,我们通常关注的是运行时多态,它通过虚函数(virtual functions)和抽象基类(abstract base classes)实现。
1. 虚函数(Virtual Functions)
虚函数是实现多态的基础。当一个基类中的函数被声明为虚函数时,任何从这个基类派生出的子类都可以重写(override)这个函数。通过基类指针或引用调用虚函数时,如果指针或引用实际指向的是派生类的对象,那么调用的将是派生类中的重写版本,而不是基类中的原始版本。
#include <iostream>
using namespace std;
class Base {
public:
virtual void show() {
cout << "Base class show()" << endl;
}
virtual ~Base() {} // 虚析构函数,确保通过基类指针删除派生类对象时,能调用到派生类的析构函数
};
class Derived : public Base {
public:
void show() override { // override关键字是C++11引入的,用于明确表示意图,不是必需的
cout << "Derived class show()" << endl;
}
};
int main() {
Base* bptr;
Derived d;
bptr = &d;
bptr->show(); // 输出:Derived class show(),因为bptr实际指向Derived类的对象
return 0;
}
2. 抽象基类(Abstract Base Classes, ABCs)
抽象基类是一种特殊的类,它至少包含一个纯虚函数(Pure Virtual Functions)。纯虚函数是在函数声明后加上= 0
来定义的,它要求任何从该基类派生的类都必须实现这个函数。抽象基类不能被实例化,因为它至少有一个函数是未定义的。
#include <iostream>
using namespace std;
class Shape {
public:
virtual void draw() const = 0; // 纯虚函数
virtual ~Shape() {}
};
class Circle : public Shape {
public:
void draw() const override {
cout << "Drawing Circle" << endl;
}
};
class Rectangle : public Shape {
public:
void draw() const override {
cout << "Drawing Rectangle" << endl;
}
};
int main() {
Shape* shape1 = new Circle();
Shape* shape2 = new Rectangle();
shape1->draw(); // 调用Circle的draw()
shape2->draw(); // 调用Rectangle的draw()
delete shape1;
delete shape2;
return 0;
}
二、多态应用场景
C++中的多态性主要用于实现接口的统一性,使得不同类的对象可以通过相同的接口(即基类中的虚函数)来执行各自特有的操作。这种特性在多种应用场景中都非常有用,比如图形界面编程、事件处理、数据库操作等。下面我将给出一个具体的案例代码,展示多态性在图形界面编程中的应用。
1. 图形绘制系统
假设我们有一个图形绘制系统,需要支持多种图形的绘制,如圆形、矩形、三角形等。每种图形都有自己的绘制方法,但我们希望通过一个统一的接口来调用这些绘制方法。
2. 案例代码
首先,我们定义一个Shape
基类,它包含一个纯虚函数draw()
,表示图形的绘制方法。然后,我们定义几个派生类,如Circle
、Rectangle
和Triangle
,它们分别继承自Shape
类并实现draw()
方法。
#include <iostream>
#include <vector>
#include <memory>
// 抽象基类
class Shape {
public:
virtual void draw() const = 0; // 纯虚函数
virtual ~Shape() {} // 虚析构函数
};
// 圆形类
class Circle : public Shape {
public:
void draw() const override {
std::cout << "Drawing Circle" << std::endl;
}
};
// 矩形类
class Rectangle : public Shape {
public:
void draw() const override {
std::cout << "Drawing Rectangle" << std::endl;
}
};
// 三角形类
class Triangle : public Shape {
public:
void draw() const override {
std::cout << "Drawing Triangle" << std::endl;
}
};
// 图形绘制系统
class GraphicsSystem {
private:
std::vector<std::unique_ptr<Shape>> shapes; // 使用智能指针管理资源
public:
void addShape(std::unique_ptr<Shape> shape) {
shapes.push_back(std::move(shape));
}
void drawAllShapes() const {
for (const auto& shape : shapes) {
shape->draw(); // 多态调用
}
}
};
int main() {
GraphicsSystem gs;
// 添加图形到系统中
gs.addShape(std::make_unique<Circle>());
gs.addShape(std::make_unique<Rectangle>());
gs.addShape(std::make_unique<Triangle>());
// 绘制所有图形
gs.drawAllShapes();
return 0;
}
3. 解释
- 基类与派生类:
Shape
是基类,定义了所有图形都应该有的draw()
方法(纯虚函数)。Circle
、Rectangle
和Triangle
是派生类,分别实现了draw()
方法。 - 图形绘制系统:
GraphicsSystem
类管理一个Shape
对象的集合,并使用std::vector<std::unique_ptr<Shape>>
来存储这些对象。这样做的好处是可以自动管理内存(通过智能指针),并且可以利用多态性通过基类指针或引用来调用派生类的draw()
方法。 - 多态性:在
drawAllShapes()
方法中,通过遍历shapes
集合并使用shape->draw()
来调用每个图形的draw()
方法。由于draw()
是虚函数,因此实际调用的是对象所属类的draw()
实现。
三、虚函数、纯虚函数
C++ 中的虚函数(Virtual Functions)和纯虚函数(Pure Virtual Functions)是面向对象编程中多态性的重要组成部分。它们允许通过基类指针或引用来调用派生类中的成员函数,从而实现接口的统一性和功能的多样性。
1. 虚函数(Virtual Functions)
虚函数是基类中声明为 virtual
的成员函数。这意味着该函数在派生类中可能有不同的实现。当通过基类指针或引用调用虚函数时,如果指针或引用实际上指向的是派生类的对象,那么将调用派生类中重写(Override)的虚函数版本,而不是基类中的原始版本。
示例代码:
#include <iostream>
class Base {
public:
virtual void show() {
std::cout << "Base class show()" << std::endl;
}
virtual ~Base() {} // 虚析构函数,确保通过基类指针删除派生类对象时,能调用到派生类的析构函数
};
class Derived : public Base {
public:
void show() override { // override是C++11的关键字,表示重写基类的虚函数
std::cout << "Derived class show()" << std::endl;
}
};
int main() {
Base* bptr = new Derived(); // 基类指针指向派生类对象
bptr->show(); // 调用Derived类的show()
delete bptr; // 释放内存
return 0;
}
2. 纯虚函数(Pure Virtual Functions)
纯虚函数是在基类中声明为 virtual
并使用 = 0
语法定义的函数。纯虚函数没有函数体(即没有大括号内的实现代码),并且要求任何从该基类派生的类都必须提供该函数的实现,除非该派生类也是抽象类(即也包含纯虚函数)。包含纯虚函数的类被称为抽象基类(Abstract Base Class, ABC),它不能被实例化。
示例代码:
#include <iostream>
class Shape {
public:
virtual void draw() const = 0; // 纯虚函数
virtual ~Shape() {} // 虚析构函数
};
class Circle : public Shape {
public:
void draw() const override {
std::cout << "Drawing Circle" << std::endl;
}
};
int main() {
// Shape s; // 错误,Shape是抽象类,不能实例化
Circle c;
c.draw(); // 调用Circle的draw()
return 0;
}
- 虚函数:允许在派生类中重写,通过基类指针或引用调用时,实际调用的是派生类中的实现。
- 纯虚函数:没有实现体,强制要求派生类提供实现,包含纯虚函数的类不能被实例化。
四、相关链接
- Visual Studio Code下载地址
- Sublime Text下载地址
- 「C++系列」C++简介、应用领域
- 「C++系列」C++ 基本语法
- 「C++系列」C++ 数据类型
- 「C++系列」C++ 变量类型
- 「C++系列」C++ 变量作用域
- 「C++系列」C++ 常量知识点-细致讲解
- 「C++系列」C++ 修饰符类型
- 「C++系列」一篇文章说透【存储类】
- 「C++系列」一篇文章讲透【运算符】
- 「C++系列」循环
- 「C++系列」判断
- 「C++系列」函数/内置函数
- 「C++系列」数字/随机数
- 「C++系列」数组
- 「C++系列」字符串
- 「C++系列」指针
- 「C++系列」引用
- 「C++系列」日期/时间
- 「C++系列」输入/输出
- 「C++系列」数据结构
- 「C++系列」vector 容器
- 「C++系列」类/对象
- 「C++系列」继承
- 「C++系列」重载运算符/重载函数