「C++系列」多态

人工智能教程】,前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。

点击跳转到网站:【人工智能教程

一、多态

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(),表示图形的绘制方法。然后,我们定义几个派生类,如CircleRectangleTriangle,它们分别继承自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. 解释

  1. 基类与派生类Shape是基类,定义了所有图形都应该有的draw()方法(纯虚函数)。CircleRectangleTriangle是派生类,分别实现了draw()方法。
  2. 图形绘制系统GraphicsSystem类管理一个Shape对象的集合,并使用std::vector<std::unique_ptr<Shape>>来存储这些对象。这样做的好处是可以自动管理内存(通过智能指针),并且可以利用多态性通过基类指针或引用来调用派生类的draw()方法。
  3. 多态性:在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;
}
  • 虚函数:允许在派生类中重写,通过基类指针或引用调用时,实际调用的是派生类中的实现。
  • 纯虚函数:没有实现体,强制要求派生类提供实现,包含纯虚函数的类不能被实例化。

在这里插入图片描述

四、相关链接

  1. Visual Studio Code下载地址
  2. Sublime Text下载地址
  3. 「C++系列」C++简介、应用领域
  4. 「C++系列」C++ 基本语法
  5. 「C++系列」C++ 数据类型
  6. 「C++系列」C++ 变量类型
  7. 「C++系列」C++ 变量作用域
  8. 「C++系列」C++ 常量知识点-细致讲解
  9. 「C++系列」C++ 修饰符类型
  10. 「C++系列」一篇文章说透【存储类】
  11. 「C++系列」一篇文章讲透【运算符】
  12. 「C++系列」循环
  13. 「C++系列」判断
  14. 「C++系列」函数/内置函数
  15. 「C++系列」数字/随机数
  16. 「C++系列」数组
  17. 「C++系列」字符串
  18. 「C++系列」指针
  19. 「C++系列」引用
  20. 「C++系列」日期/时间
  21. 「C++系列」输入/输出
  22. 「C++系列」数据结构
  23. 「C++系列」vector 容器
  24. 「C++系列」类/对象
  25. 「C++系列」继承
  26. 「C++系列」重载运算符/重载函数

猜你喜欢

转载自blog.csdn.net/xuaner8786/article/details/141711199