C++ 中虚函数与内联函数的差异

C++ 中虚函数与内联函数的差异

C++ 是一门面向对象编程语言,提供了类、对象、继承、多态等特性,是开发高质量程序的首选语言之一。C++ 中有两个关键字 virtualinline,分别用于定义虚函数和内联函数。在使用这两个关键字时,需要考虑它们带来的影响和差异。

虚函数

虚函数是一个在基类定义的函数,子类可以对其进行重写,实现多态性。虚函数的关键字是 virtual

下面是一个示例程序,其中有一个基类 Shape 和两个子类 Rectangle 和 Circle,它们分别实现了计算面积的方法 getArea()

#include <iostream>
using namespace std;

class Shape {
   protected:
      int width, height;
   public:
      Shape( int a=0, int b=0)
      {
         width = a;
         height = b;
      }
      virtual int getArea() {
         cout << "Parent class area :" << endl;
         return 0;
      }
};

class Rectangle: public Shape{
   public:
      Rectangle( int a=0, int b=0):Shape(a, b) { }
      int getArea () {
         cout << "Rectangle class area :" << endl;
         return (width * height);
      }
};

class Circle: public Shape{
   public:
      Circle( int a=0, int b=0):Shape(a, b) { }
      int getArea () {
         cout << "Circle class area :" << endl;
         return ((width/2)*(height/2)*3.14);
      }
};

int main() {
   Shape *shape;
   Rectangle rec(10,7);
   Circle cir(4,6);

   // 存储矩形的地址
   shape = &rec;
   // 调用矩形的求面积函数 area
   shape->getArea();

   // 存储圆的地址
   shape = &cir;
   // 调用圆的求面积函数 area
   shape->getArea();

   return 0;
}

运行上面的程序,输出结果如下:

Parent class area :
Parent class area :

我们注意到,getArea() 方法在 Shape 类中被声明为虚函数,在 Rectangle 和 Circle 子类的实现中被重写。在上面的代码中,我们通过 Shape 类型的指针,同时分别访问矩形和圆的面积计算方法,观察到输出结果表明 getArea() 方法被正确地调用了相应子类的方法。

内联函数

内联函数是 C++ 编译器提供的一种代码优化手段,使用 inline 关键字声明。内联函数在编译时不会像普通函数一样被调用,而是直接将函数代码插入到调用它的程序中,从而优化程序执行时间和内存的消耗。内联函数不适合于较长的函数体或者需要频繁修改的函数。

下面是一个示例程序,定义了两个函数一个是普通函数 max(),另一个是内联函数 min(),用于比较两个数的大小,并将较大值返回:

#include <iostream>
using namespace std;

inline int max(int x, int y) {
   return (x > y)? x : y;
}

int main() {
   cout << "Max value is : " << max(5, 10) << endl;
   return 0;
}

运行上面的程序,输出结果如下:

Max value is : 10

在上面的代码中,我们声明了一个内联函数 max(),在 main() 函数中调用时,编译器优化代码将函数体展开,直接取得了较大的值。这样可以避免调用函数所需要的时间和内存空间消耗。

差异

虚函数和内联函数在语法上、实现方式上有很大的区别。下面是它们的主要差异:

  1. 用法不同:虚函数通过 virtual 关键字声明,用于实现多态性;内联函数通过 inline 声明,用于代码优化和快速访问。

  2. 调用机制不同:虚函数需要通过指针或者引用调用,因为它的实际类型只有在运行时才能确定;内联函数直接被插入到调用程序的代码中,不需要额外调用,也不需要考虑虚函数表的影响。

  3. 实现方式不同:虚函数通过虚函数表和虚函数指针来实现多态性;内联函数直接将函数体插入到调用程序中,避免了函数调用的开销。

  4. 适用场景不同:虚函数适用于多态性的实现、派生类的重载和覆盖;内联函数适用于较小的函数和需要频繁调用的函数。

示例

下面是一个示例程序,演示了虚函数和内联函数的不同用法和效果:

#include <iostream>
using namespace std;

class Shape {
   protected:
      int width, height;
   public:
      Shape(int a = 0, int b = 0) {
         width = a;
         height = b;
      }
      virtual int getArea() {
         cout << "Parent class area :" << endl;
         return 0;
      }
};

class Rectangle: public Shape {
   public:
      Rectangle(int a = 0, int b = 0):Shape(a, b) { }
      int getArea () {
         cout << "Rectangle class area :" << endl;
         return (width * height);
      }
};

class Circle: public Shape {
   public:
      Circle(int a = 0, int b = 0):Shape(a, b) { }
      int getArea () {
         cout << "Circle class area :" << endl;
         return ((width/2)*(height/2)*3.14);
      }
};

inline int max(int x, int y) {
   return (x > y)? x : y;
}

int main() {
   Shape *shape;
   Rectangle rec(10, 7);
   Circle cir(4, 6);

   // 虚函数示例
   shape = &rec;
   shape->getArea();

   shape = &cir;
   shape->getArea();

   // 内联函数示例
   int x = 10, y = 20;
   cout << "Max value is : " << max(x, y) << endl;

   return 0;
}

运行上面的程序,输出结果如下:

Rectangle class area :
Circle class area :
Max value is : 20

在上面的代码中,我们同时演示了虚函数和内联函数的用法和效果。通过 Shape 类型的指针,我们调用了矩形和圆形的 getArea() 方法,观察到虚函数的多态性实现了正确的输出结果。同时,在 main() 函数中我们还使用了内联函数 max(),直接将函数体展开,实现了代码优化和快速访问。

结论

虚函数和内联函数都是 C++ 语言中的重要特性,用于实现多态性、代码优化和快速访问。虚函数通过虚函数表和虚函数指针实现多态性,适用于派生类的重载和覆盖;内联函数直接将函数体插入到调用程序中,避免了函数调用的开销,适用于较小的函数和需要频繁调用的函数。在实际开发中,根据具体情况选择适当的函数类型和参数类型,才能提高程序的可读性、可维护性和性能。

Camera课程

Python教程

Java教程

Web教程

数据库教程

图形图像教程

办公软件教程

Linux教程

计算机教程

大数据教程

开发工具教程