Virtual Methods or Function Pointers

后端 未结 8 1465
春和景丽
春和景丽 2020-12-07 11:31

When implementing polymorphic behavior in C++ one can either use a pure virtual method or one can use function pointers (or functors). For example an asynchronous callback c

8条回答
  •  佛祖请我去吃肉
    2020-12-07 12:20

    For example, let us look at an interface for adding read functionality to a class:

    struct Read_Via_Inheritance
    {
       virtual void  read_members(void) = 0;
    };
    

    Any time I want to add another source of reading, I have to inherit from the class and add a specific method:

    struct Read_Inherited_From_Cin
      : public Read_Via_Inheritance
    {
      void read_members(void)
      {
        cin >> member;
      }
    };
    

    If I want to read from a file, database, or USB, this requires 3 more separate classes. The combinations start to be come very ugly with multiple objects and multiple sources.

    If I use a functor, which happens to resemble the Visitor design pattern:

    struct Reader_Visitor_Interface
    {
      virtual void read(unsigned int& member) = 0;
      virtual void read(std::string& member) = 0;
    };
    
    struct Read_Client
    {
       void read_members(Reader_Interface & reader)
       {
         reader.read(x);
         reader.read(text);
         return;
       }
       unsigned int x;
       std::string& text;
    };
    

    With the above foundation, objects can read from different sources just by supplying different readers to the read_members method:

    struct Read_From_Cin
      : Reader_Visitor_Interface
    {
      void read(unsigned int& value)
      {
         cin>>value;
      }
      void read(std::string& value)
      {
         getline(cin, value);
      }
    };
    

    I don't have to change any of the object's code (a good thing because it is already working). I can also apply the reader to other objects.

    Generally, I use inheritance when I am performing generic programming. For example, if I have a Field class, then I can create Field_Boolean, Field_Text and Field_Integer. In can put pointers to their instances into a vector and call it a record. The record can perform generic operations on the fields, and doesn't care or know what kind of a field is processed.

提交回复
热议问题