欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

C++多态

程序员文章站 2022-04-06 12:38:52
C++多态 Polymorphism 本文为C++官网对多态阐述:http://www.cplusplus.com/doc/tutorial/polymorphism/ 在了解多态前需具备如下知识:类、结构体、友元和继承。 指向基类的指针 先来看一个基础例子 1 // pointers to bas ......

C++多态

Polymorphism

本文为C++官网对多态阐述:http://www.cplusplus.com/doc/tutorial/polymorphism/

在了解多态前需具备如下知识:类、结构体、友元和继承。

指向基类的指针

先来看一个基础例子

C++多态
 1 // pointers to base class
 2 #include <iostream>
 3 using namespace std;
 4 
 5 class Polygon {
 6   protected:
 7     int width, height;
 8   public:
 9     void set_values (int a, int b)
10       { width=a; height=b; }
11 };
12 
13 class Rectangle: public Polygon {
14   public:
15     int area()
16       { return width*height; }
17 };
18 
19 class Triangle: public Polygon {
20   public:
21     int area()
22       { return width*height/2; }
23 };
24 
25 int main () {
26   Rectangle rect;
27   Triangle trgl;
28   Polygon * ppoly1 = &rect;
29   Polygon * ppoly2 = &trgl;
30   ppoly1->set_values (4,5);
31   ppoly2->set_values (4,5);
32   cout << rect.area() << '\n';
33   cout << trgl.area() << '\n';
34   return 0;
35 }
pointers to base class

 在Rectangle和Triangle类中都含有函数area()。main函数中是分别用类对象直接调用。由于Polygon类中没有area成员函数,故ppoly1和ppoly2指针无法调用该函数。如果在基类中也能调用area()那么就不用上面代码中分别调用那么麻烦了,不过问题是area()方法不统一,没法在基类中实现。

虚成员

虚成员是一种能在派生类中重定义的成员函数,通过关键字 virtual 声明。

C++多态
 1 // virtual members
 2 #include <iostream>
 3 using namespace std;
 4 
 5 class Polygon {
 6   protected:
 7     int width, height;
 8   public:
 9     void set_values (int a, int b)
10       { width=a; height=b; }
11     virtual int area ()
12       { return 0; }
13 };
14 
15 class Rectangle: public Polygon {
16   public:
17     int area ()
18       { return width * height; }
19 };
20 
21 class Triangle: public Polygon {
22   public:
23     int area ()
24       { return (width * height / 2); }
25 };
26 
27 int main () {
28   Rectangle rect;
29   Triangle trgl;
30   Polygon poly;
31   Polygon * ppoly1 = &rect;
32   Polygon * ppoly2 = &trgl;
33   Polygon * ppoly3 = &poly;
34   ppoly1->set_values (4,5);
35   ppoly2->set_values (4,5);
36   ppoly3->set_values (4,5);
37   cout << ppoly1->area() << '\n';
38   cout << ppoly2->area() << '\n';
39   cout << ppoly3->area() << '\n';
40   return 0;
41 }
virtual members

输出结果:

20

10

0     

在Polygon类中函数 area 被声明成 virtual 因为他将被每个派生类重定义。虽然没有关键字 virtual 函数area也能派生类重定义,但是非虚成员不能被派生类通过基类引用访问。如果此处area前的virtual关键字被去掉,上面三个cout结果都会是0,因为调用的时候会被基类的函数替代。

一个声明或继承了虚函数的类被叫做多态类。

 抽象基类

抽象基类是只能被当作基类,从而被允许拥有未定义的虚成员函数(纯虚函数)。

C++多态
1 // abstract class CPolygon
2 class Polygon {
3   protected:
4     int width, height;
5   public:
6     void set_values (int a, int b)
7       { width=a; height=b; }
8     virtual int area () =0;
9 };
abstract class

注意此时 area函数未定义;他的定义被=0取代,这使它变成了一个纯虚函数。至少拥有一个纯虚函数的类叫做抽象基类。抽象类不能被实例化,但能使用其指针。

C++多态
 1 // abstract base class
 2 #include <iostream>
 3 using namespace std;
 4 
 5 class Polygon {
 6   protected:
 7     int width, height;
 8   public:
 9     void set_values (int a, int b)
10       { width=a; height=b; }
11     virtual int area (void) =0;
12 };
13 
14 class Rectangle: public Polygon {
15   public:
16     int area (void)
17       { return (width * height); }
18 };
19 
20 class Triangle: public Polygon {
21   public:
22     int area (void)
23       { return (width * height / 2); }
24 };
25 
26 int main () {
27   Rectangle rect;
28   Triangle trgl;
29   Polygon * ppoly1 = &rect;
30   Polygon * ppoly2 = &trgl;
31   ppoly1->set_values (4,5);
32   ppoly2->set_values (4,5);
33   cout << ppoly1->area() << '\n';
34   cout << ppoly2->area() << '\n';
35   return 0;
36 }
abstract base class

 这个例子中都是由基类Polygon指针调用成员函数。还能在基类中使用this指针调用派生类继承的纯虚函数。

C++多态
 1 // pure virtual members can be called
 2 // from the abstract base class
 3 #include <iostream>
 4 using namespace std;
 5 
 6 class Polygon {
 7   protected:
 8     int width, height;
 9   public:
10     void set_values (int a, int b)
11       { width=a; height=b; }
12     virtual int area() =0;
13     void printarea()
14       { cout << this->area() << '\n'; }
15 };
16 
17 class Rectangle: public Polygon {
18   public:
19     int area (void)
20       { return (width * height); }
21 };
22 
23 class Triangle: public Polygon {
24   public:
25     int area (void)
26       { return (width * height / 2); }
27 };
28 
29 int main () {
30   Rectangle rect;
31   Triangle trgl;
32   Polygon * ppoly1 = &rect;
33   Polygon * ppoly2 = &trgl;
34   ppoly1->set_values (4,5);
35   ppoly2->set_values (4,5);
36   ppoly1->printarea();
37   ppoly2->printarea();
38   return 0;
39 }
pure virtual members can be called from the abstract base class

虚成员和抽象类赋予了C++多态特性,对面向对象项目用于极大。

以下的例子结合了动态内存、类构造初始化、多态:

C++多态
 1 // dynamic allocation and polymorphism
 2 #include <iostream>
 3 using namespace std;
 4 
 5 class Polygon {
 6   protected:
 7     int width, height;
 8   public:
 9     Polygon (int a, int b) : width(a), height(b) {}
10     virtual int area (void) =0;
11     void printarea()
12       { cout << this->area() << '\n'; }
13 };
14 
15 class Rectangle: public Polygon {
16   public:
17     Rectangle(int a,int b) : Polygon(a,b) {}
18     int area()
19       { return width*height; }
20 };
21 
22 class Triangle: public Polygon {
23   public:
24     Triangle(int a,int b) : Polygon(a,b) {}
25     int area()
26       { return width*height/2; }
27 };
28 
29 int main () {
30   Polygon * ppoly1 = new Rectangle (4,5);
31   Polygon * ppoly2 = new Triangle (4,5);
32   ppoly1->printarea();
33   ppoly2->printarea();
34   delete ppoly1;
35   delete ppoly2;
36   return 0;
37 }
dynamic allocation and polymorphism

此处基类指针声明时直接用的派生类。