Comprehensive arrangement of C++ polymorphic knowledge points

Polymorphism prerequisites section finishing

  1. subclass inheritance
  2. Parent class pointer or reference
  3. Virtual functions (virtual <class name> <function name> (parameters))
    In pure object-oriented languages, all functions are polymorphic, while in hybrid languages ​​like C++, functions can be either polymorphic or non- Polymorphic, which depends on whether the binding is actually compile time or runtime
//本类为多态前提条件的案例
#include <iostream>
using namespace std;
class TradesPerson
{  public:
        virtual void sayHi()
        {   cout<<"hi."<<endl;  }
};
class Tinker : public TradesPerson
{  public:
        virtual void sayHi()
        {   cout<<"I tinker."<<endl;    }
};
class Tailor : public TradesPerson
{  public:
        virtual void sayHi()
        {   cout<<"I tailor."<<endl;    }
};
int main()
{   TradesPerson*  p;
    int which;
    do  {
        cout<<"1 == TradesPerson, 2 == Tinker, 3 == Tailor";
        cin>>which;
    } while (which < 1 || which > 3);
    switch (which)
    {   case 1 : p = new TradesPerson; break;
        case 2 : p = new Tinker; break;
        case 3 : p = new Tailor; break;
    }
    p->sayHi();  //动态绑定
    //此处用来实施对sayHi的调用
    delete p;
    return 0;
}

Array of pointers of base type, use random numbers to determine which object to generate!

#include <iostream>
#include <cstdlib>
#include <ctime>
using namespace std;
class TradesPerson
{ public:
    virtual void sayHi()  {cout<<"Just hi."<<endl;}
};
class Tinker : public TradesPerson
{ public:
    virtual void sayHi()  {cout<<"Hi, I tinker."<<endl;}
};
class Tailor : public TradesPerson
{ public:
    virtual void sayHi()  {cout<<"Hi, I tailor."<<endl;}
};

int main()  {
     srand( (unsigned) time( NULL ) ); //Sets a random starting point.
     TradesPerson*  ptrs[10];  
     unsigned  which , i ;

    for (i=0; i<10; i++) {
         which = 1 + rand() % 3;
        switch (which) {
          case 1 : ptrs[i] = new TradesPerson; break;
          case 2 : ptrs[i] = new Tinker; break;
          case 3 : ptrs[i] = new Tailor; break;
       }
   }

   for (i=0; i<10; i++) {
       ptrs[i] -> sayHi();
       delete  ptrs[ i ];
   }
   return 0;
}

When a member function of the base class is declared as a virtual function, even if the member function is not explicitly declared as a virtual function in the derived class, it will automatically become a virtual function in the derived class where it is located.
If the virtual function is defined outside the class declaration, the keyword vitual is only required at the time of declaration, and can be omitted at the time of definition.
Note: C++ only allows member functions to be defined as virtual functions, and top-level functions cannot be defined as virtual functions.

virtual void f();   //error
int main(){
    .......
}

Here is an example

#include <iostream>
using namespace std;
class High
{  protected:
     float H;
   public:
     High(float h) 
        {  H=h;}
     virtual void Show()    //在基类中定义虚函数Show()
        {  cout<<"High="<<H<<endl;}
};
class Cuboid:public High
{  private:
     float Length,Width;
   public:
     Cuboid(float l=0,float w=0,float h=0):High(h)
     {  Length=l; Width=w;}
   virtual void Show()  //在长方体派生类中定义虚函数Show()
     {  cout<<"Length="<<Length<<'\t';
        cout<<"Width="<<Width<<'\t';
        cout<<"High="<<H<<'\n'; 
        cout<<"Cuboid Volume="<<Length*Width*H<<endl;
     }    
};
class Cylinder:public High
{  private:
     float R;
   public:
     Cylinder(float r=0,float h=0):High(h)
     {R=r;}
    virtual void Show()  //在圆柱体派生类中定义虚函数Show()
     {  cout<<"Radius="<<R<<'\t';
        cout<<"High="<<H<<'\n';
        cout<<"Cylinder Volume="<<R*R*3.1415*H<<endl;
     }  
};
void main(void)
{  High h(10),*p;
   Cuboid  cu(10,10,10);
   Cylinder cy(10,10);

   h.Show();
   cu.Show();
   cy.Show();

   p=&h;
   p->Show();

   p=&cu;
   p->Show();

   p=&cy;
   p->Show();
}

Virtual functions can also be inherited! ! !

class A{
    public:
        virtual void sayHello(){cout<<"Hello"<<end1}
}
class B : public A{

}
int main(){
    B b;
    b.sayHello();
}
//结果输出Hello

Constructors cannot be virtual, but destructors can be virtual.

class A {
public: 
    virtual A();//Error
    virtual A(int);//Error
    virtual ~A();//Right
    virtual void m();
}

The reason is that virtual invocation is a mechanism that can work given incomplete information. Virtual allows to call a function. For this function, only its interface is known, but the specific type is not known. But to create an object, you must have complete information, you need to know the specific type of the created object.

Virtual destructor is really necessary, look at this code

#include <iostream>
using namespace std;
class A {
    public:
        A() { cout<<endl<<"A() firing"<<endl; //*p = new char[5]; 
        };
        ~A() {  cout<<"~A() firing"<<endl;    //delete [ ] p;
        }
    private:
        char* p;
};
class Z : public A  
{   public:
        Z() {  
            cout<<"Z() firing"<<endl;
            //q = new char[5000]; 
        };
        ~Z() {  
            cout<<"~Z() firing"<<endl;     
            //delete  [ ] q; 
        }
    private:
        char*  q;
};
void  f()
{   A*  ptr; 
    ptr  =  new  Z();
    //delete  ptr;  
}
int main() 
{   for  (unsigned i = 0; i<3; i++)  f();
    return 0;
}

If the destructor is not a virtual member function, then the compiler implements static binding! ! !
The result is a memory leak! ! !

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325485683&siteId=291194637
Recommended