35 problems caused by coverage of the same name

catalogue

Parent child compatible Assignment 1

  • Subclass objects can be used as parent objects (compatibility)

    • Subclass objects can be directly assigned to parent objects
    • Subclass objects can directly initialize parent objects
    • The parent class pointer can directly point to the subclass object: polymorphism
    • Parent class references can directly reference child class objects
  • Example: compatibility of subclass objects

    • Demo

      #include <iostream>
      #include <string>
      
      using namespace std;
      
      class Parent
      {
      public:
          int mi;
          
          void add(int i)
          {
              mi += i;
          }
          
          void add(int a, int b)
          {
              mi += (a + b);
          }
      };
      
      class Child : public Parent
      {
      public:
          int mv;
          
          void add(int x, int y, int z)
          {
              mv += (x + y + z);
          }
      };
      
      int main()
      {
          Parent p;
          Child c;
          
          p = c;
          
          Parent p1(c);
          
          
          Parent& rp = c;  //Parent class reference: refers to a subclass object
          Parent* pp = &c;  //Parent class pointer: points to a child class object
          
          rp.mi = 100;
          rp.add(5);             // No overwrite with the same name occurred
          rp.add(10, 10);        // No overwrite with the same name occurred
          
          //Compilation error
          pp->mv = 1000;
          pp->add(1, 10, 100);
          
          return 0;
      }
      
    • compile

      test.cpp: In fuction 'int main()':
      test.cpp:51: error: 'class Parent' has no member named 'mv'
      test.cpp:52: error: no matching function for call to 'Parent::add(int,int,int)'
      test.cpp:11:note: candidates are: void Parent::add(int)
      test.cpp:16:note:                 void Parent::add(int,int)
      
  • When using a parent class pointer (Reference) to point to a child class object

    • A subclass object degenerates into a parent object
    • Only members defined in the parent class can be accessed
    • You can directly access the members with the same name that are overwritten by the subclass. For example, add(int) and add(int,int) of the parent class are overwritten by add(int,int,int) of the subclass

2 special functions with the same name

  • You can redefine the existing member functions in the parent class in the subclass: the reason for redefinition is that the functions in the parent class cannot be used

  • This definition occurs in inheritance and is called function rewriting

  • Function rewriting is a special case of covering with the same name

    class Parent
    {
    public:
        void print()
        {
            cout << "I'm Parent." << endl;
        }
    };
    
    //Function rewriting
    class Child : public Parent
    {
    public:
        //The function prototype is exactly the same as that in the parent class. Function rewriting is necessary here
        void print()
        {
            cout << "I'm Child." << endl;
        }
    };
    
  • Question: what happens when a function rewrite encounters assignment compatibility?

  • Example: function rewriting VS assignment compatibility

    • Demo

      #include <iostream>
      #include <string>
      
      using namespace std;
      
      class Parent
      {
      public:
          int mi;
          
          void add(int i)
          {
              mi += i;
          }
          
          void add(int a, int b)
          {
              mi += (a + b);
          }
          
          //Print parent class information
          void print()
          {
              cout << "I'm Parent." << endl;
          }
      };
      
      class Child : public Parent
      {
      public:
          int mv;
          
          void add(int x, int y, int z)
          {
              mv += (x + y + z);
          }
          
          //Rewrite function: print subclass information
          void print()
          {
              cout << "I'm Child." << endl;
          }
      };
      
      void how_to_print(Parent* p)
      {
          p->print();
      }
      
      int main()
      {
          Parent p;
          Child c;
          
          p.print();
          c.print();
          
          how_to_print(&p);    // Expected to print: I'm Parent.
          how_to_print(&c);    // Expected to print: I'm Child.
          
          return 0;
      }
      
    • Compile and run

      I'm Parent.
      I'm Child.
      
      I'm Parent.
      I'm Parent.  !!!!!!
      
  • problem analysis

    • During compilation, the compiler can only judge the object pointed to according to the type of pointer

    • According to assignment compatibility, the compiler considers that the parent class pointer points to the parent class object

    • Therefore, the compilation result can only be to call the function with the same name defined in the parent class

    • When compiling the following functions, the compiler cannot know what the pointer p points to, but there is no reason for the compiler to report an error. Therefore, the compiler believes that the safest way is to call the print function of the parent class, because the parent and child classes must have the same print function. But not expected! = > Using polymorphic resolution

      void how_to_print(Parent* p)
      {
          p->print();
      }
      

Tags: C++

Posted by steved on Mon, 09 May 2022 17:11:51 +0300