乐趣区

关于c++:C虚函数详解多态性实现原理及其在面向对象编程中的应用

在面向对象的编程中,多态性是一个十分重要的概念。多态性意味着在不同的上下文中应用同一对象时,能够产生不同的行为。C++ 是一种面向对象的编程语言,在 C ++ 中,虚函数是实现多态性的要害

什么是虚函数

虚函数是一个在基类中申明的函数,它能够被子类重写并提供不同的实现。在 C ++ 中,应用关键字 virtual 来申明一个虚函数。虚函数的原理是将函数调用的控制权交给运行时环境,而不是编译时环境。因而,虚函数的实现须要在运行时能力确定。虚函数的申明模式如下:

 virtual 返回类型 函数名(参数列表) {// 实现代码}

例如:

 class Shape {
   public:
     virtual void draw() {// 实现代码}
 };
 
 class Circle : public Shape {
   public:
     void draw() override {// 实现代码}
 };

在下面的例子中,Shape类定义了一个虚函数 draw(),并在Circle 类中重写了它。留神,在 Circle 类中的重写函数中应用了 override 关键字,这是 C ++11 中引入的新个性,示意该函数是对基类中同名函数的重写。

多态性的实现

当应用基类指针或援用来拜访派生类对象时,如果虚函数已被重写,将调用派生类中的实现。这种行为称为运行时多态性,因为理论调用的函数是在运行时确定的。例如:

 Shape* s = new Circle();
 s->draw(); // 调用 Circle 类中的 draw()函数

在下面的例子中,咱们应用基类指针 s 来拜访 Circle 类的对象,因为 Circle 类重写了 draw() 函数,所以调用的是 Circle 类中的实现。这种行为能够使代码更加灵便、可扩大和易于保护。多态性的实现有两种形式:动态多态和动静多态。动态多态是通过函数重载实现的,而动静多态是通过虚函数实现的。

动态多态是在编译时确定函数的调用,函数重载是动态多态的一种模式。例如:

 void print(int a) {// 实现代码}
 
 void print(float b) {// 实现代码}

在下面的例子中,咱们定义了两个函数 print(),一个承受一个整数参数,另一个承受一个浮点数参数。在调用print() 函数时,编译器会依据传递的参数类型确定调用哪个函数。

动静多态是在运行时确定函数的调用。虚函数是动静多态的一种模式。在应用虚函数时,能够将基类指针或援用指向派生类对象,这样就能够实现多态性调用。例如:

 Shape* s = new Circle();
 s->draw(); // 调用 Circle 类中的 draw()函数

在下面的例子中,咱们应用基类指针 s 来拜访 Circle 类的对象,因为 Circle 类重写了 draw() 函数,所以调用的是 Circle 类中的实现。这种行为称为运行时多态性,因为理论调用的函数是在运行时确定的。

多态的底层原理

在 C ++ 中,多态是通过虚函数表和虚指针来实现的。虚函数表是一个非凡的表格,其中蕴含了虚函数的地址。每个类都有一个虚函数表,其中蕴含了该类及其基类的虚函数地址。当一个对象被创立时,它将蕴含一个指向其类的虚函数表的指针,称为虚指针。当调用一个虚函数时,程序将首先查找该对象的虚指针,而后应用虚指针中的虚函数表来查找正确的函数地址。这种办法使得程序在运行时可能动静地抉择正确的函数。

多态性的益处

多态性能够使代码更加灵便、可扩大和易于保护。多态性能够使代码更加通用,能够使同样的代码实用于不同的对象。多态性能够进步代码的复用性,能够缩小代码的反复编写。多态性能够使代码更加易于保护,因为代码能够更加清晰、简洁和易于了解。

在理论编程中,多态性也是十分有用的。例如,咱们能够应用多态性来编写一个通用的排序函数,该函数能够对不同类型的数据进行排序。另一个例子是图形界面编程,咱们能够应用多态性来解决不同的用户输出事件。

总结

虚函数是实现多态性的要害,它容许不同的对象体现出不同的行为。当应用基类指针或援用来拜访派生类对象时,虚函数将调用派生类中的实现,实现了运行时多态性。在面向对象的编程中,多态性是一个十分重要的概念,能够使代码更加灵便、可扩大和易于保护。多态性有两种模式:动态多态和动静多态。动态多态是通过函数重载实现的,而动静多态是通过虚函数实现的。虚函数的底层原理能够参考我之前的帖子,有具体的介绍,这里不做多开展。最初,多态性能够使代码更加通用、易于保护和进步复用性。

退出移动版