C++ 纯虚函数 — 抽象接口

前言 :C++中纯虚函数 是一个重要的特性、方法,若正确使用能够优化代码结构,提升层次性,增强可阅读性。在之前的文章中(C++ 虚函数 解析指南-CSDN博客),一笔带过了纯虚函数的介绍,本文将对纯虚函数做一些详细的解读,希望能够为童鞋们平时的项目开发提供新的思路和帮助。

目录

一、纯虚函数基本概念和语法

二、纯虚函数的作用

三、纯虚函数代码示例

[3.1 抽象基类Shape](#3.1 抽象基类Shape)

[3.2 派生类Rectangle](#3.2 派生类Rectangle)

[3.3 派生类Circle](#3.3 派生类Circle)

[3.4 基类指针实现多态](#3.4 基类指针实现多态)

四、纯虚析构函数

五、纯虚函数的高级应用

[5.1 抽象接口设计](#5.1 抽象接口设计)

[5.2 工厂模式](#5.2 工厂模式)

[5.3 模板方法模式](#5.3 模板方法模式)

六、纯虚函数可以有实现吗


一、纯虚函数基本概念和语法

C++中,纯虚函数是一种特殊的虚函数,它在基类中声明但没有提供实现。纯虚函数通过在声明后添加**=0**来标识:

cpp 复制代码
virtual void functionName() = 0; // 声明纯虚函数

在类中声明虚函数:

cpp 复制代码
class AbstractClass {
public:
    // 声明一个纯虚函数
    virtual void pureVirtualFunc() = 0;
    // ... 其他成员函数
private:
    // ... 数据成员
};

关于纯虚函数定义与使用 需要注意:

  • 纯虚函数一般只有函数声明,没有函数体
  • 在函数声明的末尾添加**=0**,其作用是形式上告诉编译器这是一个纯虚函数
  • 包含纯虚函数的类称为抽象类,抽象类无法进行实例化(即,无法定义对象)
  • 派生类必须重写(override)基类中的纯虚函数,并提供该函数的具体实现,否则该派生类仍然被视为抽象类

二、纯虚函数的作用

那么纯虚函数的好处在哪里,为什么C++要引入纯虚函数呢?

纯虚函数主要为了解决在面向对象程序设计中常见的一些问题,并提供一种强制性的接口约定。其主要好处包括:

  • 抽象接口:通过在基类中声明纯虚函数,可以为派生类定义一个统一的抽象接口规范。所有派生类都必须实现这个接口,从而确保它们都提供了基类中所声明的行为。
  • 强制实现:纯虚函数的存在强制派生类必须提供该函数的实现,否则派生类也将成为抽象类,无法实例化。这种机制确保了接口的一致性,避免了派生类遗漏重要功能的实现。
  • 多态性支持:纯虚函数本身是虚函数的一种,因此它支持运行时多态。通过基类指针或引用调用纯虚函数时,实际调用的是派生类中重写的实现,从而实现多态行为。
  • 避免实例化不合理的对象:某些基类本身并不需要实例化(例如"形状"基类),它们的存在只是为了提供一个抽象概念。通过将其设计为抽象类(包含纯虚函数),可以防止用户直接实例化不合理的对象,从而提高代码的结构层次与可读性。

三、纯虚函数代码示例

这里举一个例子说明,如何使用抽象类和纯虚函数来定义形状相关的一些接口,并由派生类提供具体实现。

3.1 抽象基类Shape

首先,定义一个抽象基类Shape,其中声明了纯虚函数getArea(),用于计算形状的面积。此外,为了完整性,还包含了一个非纯虚的析构函数,以确保正确释放资源。

cpp 复制代码
class Shape {
public:
    virtual ~Shape() {}  // 虚析构函数,确保正确析构
    // 纯虚函数:计算面积,仅接口 无实现
    virtual double getArea() const = 0;
};

3.2 派生类Rectangle

其次,定义一个派生类Rectangle ,继承自Shape,并提供getArea()函数的具体实现。

cpp 复制代码
class Rectangle : public Shape {
public:
    Rectangle(double len, double wid) : length(len), width(wid) {}
    // 实现纯虚函数:计算矩形的面积
    double getArea() const override {
        return length * width;
    }
private:
    double length;
    double width;
};

3.3 派生类Circle

同样,定义另一个派生类Circle,继承自Shape,并提供getArea()函数的具体实现。

cpp 复制代码
class Circle : public Shape {
public:
    Circle(double r) : radius(r) {}
    // 实现纯虚函数:计算圆形的面积
    double getArea() const override {
        return 3.14159265 * radius * radius;
    }
private:
    double radius;
};

3.4 基类指针实现多态

在main()函数中,我们定义一个基类指针Shape*,并让该指针指向派生类Rectangle或Circle的对象。通过这个指针调用getArea()函数,可以实现多态行为

cpp 复制代码
int main() {
    Shape* shape1 = new Rectangle(10.0, 5.0);  // 指向 Rectangle 对象
    Shape* shape2 = new Circle(7.0);          // 指向 Circle 对象

    // 调用纯虚函数 getArea()
    cout << "Area of rectangle: " << shape1->getArea() << endl;
    cout << "Area of circle: " << shape2->getArea() << endl;

    delete shape1;
    delete shape2;
    return 0;
}

四、纯虚析构函数

析构函数(Destructor)用于在对象生命周期结束时执行清理工作。将析构函数声明为虚函数可以确保通过基类指针删除派生类对象时,调用正确的析构函数序列。

纯虚析构函数的作用:如果基类的析构函数被声明为纯虚函数,那么该基类成为抽象类,派生类必须实现析构函数,否则该派生类也将成为抽象类,无法实例化。这种机制强制派生类提供析构函数的实现,确保了析构函数的完整性。

五、纯虚函数的高级应用

纯虚函数在实际项目中的应用非常广泛,特别是在需要定义接口、强制实现一致性和实现多态行为的场景中。

5.1 抽象接口设计

接口设计:纯虚函数是定义接口的主要手段之一。通过在抽象类中声明一组纯虚函数,可以定义清晰的接口规范,供其他类实现。这种设计提高了代码的模块化和可维护性。

5.2 工厂模式

工厂模式:工厂模式经常与纯虚函数结合使用。工厂基类可以提供一个纯虚函数用于创建产品对象,具体的工厂类通过重写该函数来创建特定类型的产品。

5.3 模板方法模式

模板方法模式:模板方法模式在基类中定义算法的骨架,将某些步骤定义为纯虚函数,由派生类实现具体步骤。

六、纯虚函数可以有实现吗

上文提到纯虚函数一般来说 只有声明,没有实现。其实,纯虚函数是可以有实现的,这是很多人忽略的一个点。

  • 纯虚函数可以在类外提供实现(但类内的声明仍然是 = 0)。
  • 派生类可以"显式调用"这个实现。

举个简单示例:

cpp 复制代码
class Base {
public:
    virtual void foo() = 0;  // 纯虚函数
};

void Base::foo() {          // 类外提供实现
    // ... 实现体
}

class Derived : public Base {
public:
    void foo() override {
        // 可以在这里调用 Base 的实现
        Base::foo();

        // 再加上派生类自己的行为
    }
};
相关推荐
其古寺2 小时前
阿里TTL框架全面解读
经验分享
秦奈2 小时前
Unity复习学习笔记(九):UGUI
笔记·学习·unity
SR_shuiyunjian2 小时前
Python第一次作业
开发语言·python·算法
停走的风2 小时前
anaconda与pycharm卸载重安装笔记
笔记·pycharm·conda
云深麋鹿2 小时前
一.算法复杂度
c语言·开发语言·算法
wen__xvn2 小时前
码蹄杯刷题
数据结构·c++·算法
少控科技2 小时前
QT进阶日记009
开发语言·qt
CodeCraft Studio2 小时前
从框架到体验:Qt + Qtitan 构建制造业嵌入式UI整体解决方案
开发语言·qt·ui·gui·嵌入式开发·hmi·制造业嵌入式ui