C++ 中虚函数与内联函数的差异
C++ 是一门面向对象编程语言,提供了类、对象、继承、多态等特性,是开发高质量程序的首选语言之一。C++ 中有两个关键字 virtual
和 inline
,分别用于定义虚函数和内联函数。在使用这两个关键字时,需要考虑它们带来的影响和差异。
虚函数
虚函数是一个在基类定义的函数,子类可以对其进行重写,实现多态性。虚函数的关键字是 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 = ○
// 调用圆的求面积函数 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() 函数中调用时,编译器优化代码将函数体展开,直接取得了较大的值。这样可以避免调用函数所需要的时间和内存空间消耗。
差异
虚函数和内联函数在语法上、实现方式上有很大的区别。下面是它们的主要差异:
- 用法不同:虚函数通过
virtual
关键字声明,用于实现多态性;内联函数通过inline
声明,用于代码优化和快速访问。 -
调用机制不同:虚函数需要通过指针或者引用调用,因为它的实际类型只有在运行时才能确定;内联函数直接被插入到调用程序的代码中,不需要额外调用,也不需要考虑虚函数表的影响。
-
实现方式不同:虚函数通过虚函数表和虚函数指针来实现多态性;内联函数直接将函数体插入到调用程序中,避免了函数调用的开销。
-
适用场景不同:虚函数适用于多态性的实现、派生类的重载和覆盖;内联函数适用于较小的函数和需要频繁调用的函数。
示例
下面是一个示例程序,演示了虚函数和内联函数的不同用法和效果:
#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 = ○
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++ 语言中的重要特性,用于实现多态性、代码优化和快速访问。虚函数通过虚函数表和虚函数指针实现多态性,适用于派生类的重载和覆盖;内联函数直接将函数体插入到调用程序中,避免了函数调用的开销,适用于较小的函数和需要频繁调用的函数。在实际开发中,根据具体情况选择适当的函数类型和参数类型,才能提高程序的可读性、可维护性和性能。