C++ 虚函数与纯虚函数

目录

[1. 虚函数](#1. 虚函数)

[2. 纯虚函数](#2. 纯虚函数)


C++ 中的虚函数和纯虚函数都是实现多态的重要机制。多态可以让不同的对象以相同的方式进行操作,从而简化代码的编写和维护。

1. 虚函数

虚函数是一种在基类中声明的函数,可以在派生类中进行重写。在运行时,根据对象的类型确定调用的函数版本,这就是所谓的动态绑定,运行时多态。

在C++中,将一个成员函数声明为虚函数,只需要在函数声明前加上virtual关键字。如果在基类中声明了一个虚函数,派生类中的同名函数也将自动成为虚函数,除非显式地指定为非虚函数。

虚函数的一个重要作用是实现运行时多态。在基类指针或引用指向派生类对象(方便统一接口)时,通过虚函数可以调用派生类中实现的版本,而不是基类中的版本。这种行为被称为虚函数重写(override),它可以让不同的对象以相同的方式进行操作。

举个栗子:

复制代码
#include <iostream>
 
using namespace std;
 
class Shape {
public:
  virtual double area() const {
    return 0;
  }
};
 
class Rectangle : public Shape {
public:
  Rectangle(double w, double h) : width(w), height(h) {}
  virtual double area() const {
    return width * height;
  }
private:
  double width, height;
};
 
class Circle : public Shape {
public:
  Circle(double r) : radius(r) {}
  virtual double area() const {
    return 3.1415926 * radius * radius;
  }
private:
  double radius;
};
 
int main() {
  Shape* shapes[] = {new Rectangle(3, 4), new Circle(2)};
  for (int i = 0; i < 2; i++) {
    cout << "Area: " << shapes[i]->area() << endl;
  }
  return 0;
}

在这个示例中,我们定义了一个Shape基类,它包含一个虚函数area。Rectangle和Circle派生类分别重写了area函数,并实现了各自的面积计算方法。在main函数中,我们创建了一个Shape类型的指针数组,并将其指向两个不同类型的对象。通过调用虚函数area****,我们可以使用相同的方式计算这两个对象的面积,而不必考虑它们的具体类型。(实现调用接口的统一,都用基类指针进行调用就行,因为基类定义了虚函数会自动生成一个虚函数指针指向虚函数表,子类的重写入口放在虚函数表中)

2. 纯虚函数

纯虚函数是一种特殊的虚函数,它没有函数体,需要在派生类中进行实现。定义纯虚函数的语法是在函数声明后面加上"=0"。包含纯虚函数的类被称为抽象类,不能实例化对象,只能用于派生其他类。

**纯虚函数的一个重要作用是定义接口。通过在基类中定义一组纯虚函数,可以明确指定子类必须实现的方法。**这可以保证派生类的一致性,同时也可以简化代码的设计和维护。

举个栗子:

复制代码
#include <iostream>
 
using namespace std;
 
class Shape {
public:
  virtual double area() const = 0;
  virtual void draw() const = 0;
};
 
class Rectangle : public Shape {
public:
  Rectangle(double w, double h) : width(w), height(h) {}
  virtual double area() const {
    return width * height;
  }
  virtual void draw() const {
    cout << "Drawing a rectangle" << endl;
  }
private:
  double width, height;
};
 
class Circle : public Shape {
public:
  Circle(double r) : radius(r) {}
  virtual double area() const {
    return 3.1415926 * radius * radius;
  }
  virtual void draw() const {
    cout << "Drawing a circle" << endl;
  }
private:
  double radius;
};
 
int main() {
  Shape* shapes[] = {new Rectangle(3, 4), new Circle(2)};
  for (int i = 0; i < 2; i++) {
    cout << "Area: " << shapes[i]->area() << endl;
    shapes[i]->draw();
  }
  return 0;
}

在这个示例中,我们在Shape基类中定义了两个纯虚函数area和draw。这个基类不能被实例化,只能被用于派生其他类。Rectangle和Circle派生类分别实现了area和draw函数,并实现了各自的面积计算方法和绘制方法。在main函数中,我们创建了一个Shape类型的指针数组,并将其指向两个不同类型的对象。通过调用纯虚函数area和draw,我们可以使用相同的方式计算这两个对象的面积并绘制它们,而不必考虑它们的具体类型。

需要注意的是,**纯虚函数必须在派生类中进行实现,否则派生类也将变成抽象类。**如果在派生类中不想实现某个纯虚函数,可以将其声明为虚函数,并提供一个默认实现。这个默认实现可以是一个空函数体,也可以是一个具体的实现,具体的实现可能会在某些情况下有用。

总之,**虚函数和纯虚函数是C++中实现多态的重要机制。**通过虚函数和纯虚函数,我们可以实现运行时多态和定义接口。这可以让不同的对象以相同的方式进行操作,从而简化代码的编写和维护。

参考: C++中虚函数和纯虚函数详解_c++ 虚函数和纯虚函数_不见白鹿的博客-CSDN博客

相关推荐
青瓦梦滋5 小时前
WebSocket协议
linux·服务器·网络·c++·websocket·网络协议·http
CodeYp201910 小时前
第15讲:二叉搜索树
开发语言·c++·二叉搜索树
pipixia2003311 小时前
C++继承面试四连问:内存叠加、私有继承、sizeof、权限重映射
c++·面试·嵌入式·继承·面向对象·对象模型
牵猫散步的鱼儿14 小时前
C++ 内存分区
c++
choumin14 小时前
C++ 标准容器为什么不能存引用
c++·容器·引用类型
谙弆悕博士14 小时前
用 C 写了个 Windows 聊天室,踩了几个多线程和控制台的坑
c语言·开发语言·c++·windows·网络编程·聊天室
stolentime15 小时前
CF2277E Tree Guessing题解
c++·算法·贪心算法·交互·ad-hoc
syagain_zsx16 小时前
ODB 与 MySQL:C++ 里的 ORM 实践(类即表、事务铁律与查询封装)
开发语言·数据库·c++·mysql·工具库·1024程序员节
小鱼仙官16 小时前
使用Qt封装C/C++ 动态库 用于第三方调用
c语言·c++·qt
晚风予卿云月16 小时前
【C++高并发内存池】 1.定长内存池的实现
开发语言·c++·内存管理