【译】多态(二)

抽象基类

抽象基类很像我们之前例子的CPolygon类。唯一的区别是,之前的例子中我们为CPolygon类的对象(如poly)定义了一个具有最少功能的有效函数area(),而抽象基类中不能为area()成员函数提供任何实现。这通过在函数声明后加上“=0”实现。 

一个抽象基类CPolygon可能像这样:

// abstract class CPolygon 

class CPolygon { 

  protected: 

    int width, height; 

  public: 

    void set_values (int a, int b) 

      { width=a; height=b; } 

    virtual int area () =0; 

};

注意到我们在virtual int area()后加了“=0”,代替此函数的实现。这种类型的函数称为纯虚函数,含有至少一个纯虚函数的类称为抽象基类。 

抽象基类与普通多态类的主要区别在于,不能被实例化,因为在抽象基类中至少存在一个缺少实现的成员。 

不过,一个不能实例化对象的类并不是全然无用。我们可以创建它的指针,并利用它的多态特性。因此,如下的声明:

CPolygon poly;

对于我们声明的抽象基类是无效的,因为试图实例化一个对象。不过,如下的指针:

CPolygon * ppoly1;

CPolygon * ppoly2;

却是完全合法的。 

至此,既然CPolygon包含一个纯虚函数,它就是一个抽象基类。不管怎样,这个抽象基类的指针可以用来指向其派生类的对象。 

这里是完整的例子:

// abstract base class 

#include <iostream> 

using namespace std; 

 

class CPolygon { 

  protected: 

    int width, height; 

  public: 

    void set_values (int a, int b) 

      { width=a; height=b; } 

    virtual int area (void) =0; 

  }; 

 

class CRectangle: public CPolygon { 

  public: 

    int area (void) 

      { return (width * height); } 

  }; 

 

class CTriangle: public CPolygon { 

  public: 

    int area (void) 

      { return (width * height / 2); } 

  }; 

 

int main () { 

  CRectangle rect; 

  CTriangle trgl; 

  CPolygon * ppoly1 = &rect; 

  CPolygon * ppoly2 = &trgl; 

  ppoly1->set_values (4,5); 

  ppoly2->set_values (4,5); 

  cout << ppoly1->area() << endl; 

  cout << ppoly2->area() << endl; 

  return 0; 

}

输出:20 10 

如果重新审视一下这段程序,你会发现我们用同一类型的指针(CPolygon*)访问了不同的对象。这会非常有用。例如,现在我们为抽象基类CPolygon创建一个函数成员来在屏幕上打印area()的结果,尽管CPolygon类自己没有此函数的实现:

// pure virtual members can be called 

// from the abstract base class 

#include <iostream> 

using namespace std; 

 

class CPolygon { 

  protected: 

    int width, height; 

  public: 

    void set_values (int a, int b) 

      { width=a; height=b; } 

    virtual int area (void) =0; 

    void printarea (void) 

      { cout << this.>area() << endl; } 

  }; 

 

class CRectangle: public CPolygon { 

  public: 

    int area (void) 

      { return (width * height); } 

  }; 

 

class CTriangle: public CPolygon { 

  public: 

    int area (void) 

      { return (width * height / 2); } 

  }; 

 

int main () { 

  CRectangle rect; 

  CTriangle trgl; 

  CPolygon * ppoly1 = &rect; 

  CPolygon * ppoly2 = &trgl; 

  ppoly1->set_values (4,5); 

  ppoly2->set_values (4,5); 

  ppoly1->printarea(); 

  ppoly2->printarea(); 

  return 0; 

}

输出:20 10

虚成员和抽象基类赋予了C++多态特性,这使得面向对象的编程方法对大型工程来说是如此有用。当然,我们已经看到了这些特性的非常简单的应用,但是这些特性可以用在对象数组或动态创建的对象上。

我们再次以同样的例子结尾,但这次对象是动态创建的: 

// dynamic allocation and polymorphism 

#include <iostream> 

using namespace std; 

 

class CPolygon { 

  protected: 

    int width, height; 

  public: 

    void set_values (int a, int b) 

      { width=a; height=b; } 

    virtual int area (void) =0; 

    void printarea (void) 

      { cout << this.>area() << endl; } 

  }; 

 

class CRectangle: public CPolygon { 

  public: 

    int area (void) 

      { return (width * height); } 

  }; 

 

class CTriangle: public CPolygon { 

  public: 

    int area (void) 

      { return (width * height / 2); } 

  }; 

 

int main () { 

  CPolygon * ppoly1 = new CRectangle; 

  CPolygon * ppoly2 = new CTriangle; 

  ppoly1->set_values (4,5); 

  ppoly2->set_values (4,5); 

  ppoly1->printarea(); 

  ppoly2->printarea(); 

  delete ppoly1; 

  delete ppoly2; 

  return 0; 

}

 

输出:20 10

 

原文:http://www.cplusplus.com/doc/tutorial/polymorphism/

你可能感兴趣的:(多态)