zoukankan      html  css  js  c++  java
  • 【译】多态(二)

    抽象基类

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

  • 相关阅读:
    LeetCode 485. Max Consecutive Ones
    LeetCode 367. Valid Perfect Square
    LeetCode 375. Guess Number Higher or Lower II
    LeetCode 374. Guess Number Higher or Lower
    LeetCode Word Pattern II
    LeetCode Arranging Coins
    LeetCode 422. Valid Word Square
    Session 共享
    java NIO
    非阻塞IO
  • 原文地址:https://www.cnblogs.com/dahai/p/2057213.html
Copyright © 2011-2022 走看看