位置:首页 > 高级语言 > C++在线教程 > C++多态

C++多态

这个词多态是指有多种形式。通常情况下,当有一个类层次并且它们通过继承关系产生多态。

C++多态意味着调用一个成员函数将产生不同的功能结果,以根据所调用的函数的对象的类型来执行。

考虑下面的例子,其中一个基类是来自其它两个类:

#include <iostream> 
using namespace std;
 
class Shape {
   protected:
      int width, height;
   public:
      Shape( int a=0, int b=0)
      {
         width = a;
         height = b;
      }
      int area()
      {
         cout << "Parent class area :" <<endl;
         return 0;
      }
};
class Rectangle: public Shape{
   public:
      Rectangle( int a=0, int b=0):Shape(a, b) { }
      int area ()
      { 
         cout << "Rectangle class area :" <<endl;
         return (width * height); 
      }
};
class Triangle: public Shape{
   public:
      Triangle( int a=0, int b=0):Shape(a, b) { }
      int area ()
      { 
         cout << "Triangle class area :" <<endl;
         return (width * height / 2); 
      }
};
// Main function for the program
int main( )
{
   Shape *shape;
   Rectangle rec(10,7);
   Triangle  tri(10,5);

   // store the address of Rectangle
   shape = &rec;
   // call rectangle area.
   shape->area();

   // store the address of Triangle
   shape = &tri;
   // call triangle area.
   shape->area();
   
   return 0;
}

让我们编译和运行上面的程序,这将产生以下结果:

Parent class area
Parent class area

不正确的输出是调用函数area() 的原因是由编译器在基类中定义的版本设置的。这就是所谓的静态解析函数调用,或静态链接- 在执行程序之前的函数调用是固定的。此有时也被称为早期绑定,因为area()函数在程序汇编时设置。

但现在,让我们在我们的程序稍作修改和声明area() ,在Shape类的前面加上关键字virtual,使其看起来像这样:

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

这种轻微修改后,在前面的示例代码被编译和执行时,它产生了以下结果:

Rectangle class area
Triangle class area

此时,编译器着眼于指针,而不是它的类型的内容。因此,由于tri 和 rec类的对象的地址存储在*shape 的各自area()函数被调用。

正如你所看到的,每个子类具有独立实现area()函数。这是是如何多态通常使用。不同的类具有相同函数名称,并且即使相同的参数,但也可以有不同的实现。

虚拟函数:

虚函数是在使用关键字的虚拟声明的基类的函数。定义在基类中的虚函数,与其他版本在派生类不同,我们不希望这个函数静态链接编译器。

我们所要的是函数的选择被调用在程序中任何给定的点是基于用于调用它的类的对象。这种操作被称为动态链接,或后期绑定。

纯虚函数:

这是可能的,想包括在基类中的虚函数,以便它可以在派生类中被重新定义,以适应该类的对象,但没有实际的定义,可以在基类中声明函数。

我们可以改变所述虚拟函数area()的基类为以下:

class Shape {
   protected:
      int width, height;
   public:
      Shape( int a=0, int b=0)
      {
         width = a;
         height = b;
      }
      // pure virtual function
      virtual int area() = 0;
};

= 0表明该函数没有主体和上述虚函数被编译器调用。