【译】多态(二)

抽象基类

抽象基类很像我们之前例子的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/

posted @ 2011-05-25 19:21  iThinking  阅读(231)  评论(0编辑  收藏  举报