多态性和虚函数

多态

相同的方法或者函数调用为不同的对象所接受时可能导致的不同行为,这种现象称为类的多态性。具体的说,它主要表现在函数调用时,实现一种接口,多种方法,多态性是面向对象程序设计的另一个重要特征。C++支持两种多态性,编译时多态性和运行时的多态性。

编译时的多态性指的是属于某个类的不同对象,或不同环境下的同一对象,调用了名称相同的成员函数,所完成的功能却不相同,这是一种静态多态性,因为编译器在对源程序进行编译时,即可确定所要调用的是哪个函数或者,通过重载机制即可实现。

运行时多态性指的是属于某个基类的不同派生对象,在形式上调用的是继承自己基类的同一成员函数。实际上调用的却是各自派生的同名成员函数,这是一种动态多态性,因为函数名,函数参数和返回类型,都相同的情况下,编译阶段不能确定要调用的函数,只能在程序运行时确定这种多态性,这种多态性通过虚函数机制来实现。

派生类对象替换基类对象

通过公用继承方式创建的派生类,继承了基类成员及其访问权限,因此公用派生类对象可以替代基类对象,完成本来由基类对象所完成的任务。派生类对象替换基类的原则是,凡是机内出现的地方都可以用,公用派生类对象取代这种取代有以下三种情况:
1.派生类对象给基类对象赋值
2.派生类对象初始化基类对象的引用
3.使基类的指针指向派生类对象(实现虚函数的关键)

class Base                                                                                                                                               
{                                                                                                                                                        
  public:                                                                                                                                                
      void funpublic()                                                                                                                            
    {                                                                                                                                                    
      cout<<"基类的成员函数"<<endl;                                                                                                                      
    }                                                                                                                                                    
};                                                                                                                                                       

class child1:public Base                                                                                                                                 
{                                                                                                                                                        
  public:                                                                                                                                                
    void funpublic()                                                                                                                                     
    {                                                                                                                                                    
      cout<<"派生类child1的成员函数"<<endl;                                                                                                              
    }                                                                                                                                                    
};                                                                                                                                                       


class child2:public Base                                                                                                                                 

{                                                                                                                                                        
  public:                                                                                                                                                
    void funpublic()                                                                                                                                     
    {                                                                                                                                                    
      cout <<"派生类child2的成员函数"<<endl;                                                                                                             
    }                                                                                                                                                    
};
int main() {                                                                                                                                             
  Base * p1,*p2,*p3,base;                                                                                                                                

  child1 obj1;                                                                                                                                           
  child2 obj2;                                                                                                                                           
  base =obj1;                                                                                                                                            
  base.funpublic();                                                                                                                                      
  Base  &aliasbase=obj2;                                                                                                                                 
  aliasbase.funpublic();                                                                                                                                 
  p1=&obj1;                                                                                                                                              
  p2=&obj2;                                                                                                                                              
  p1->funpublic();                                                                                                                                       
  p2->funpublic();                                                                                                                                       
  p2=new child1;                                                                                                                                         
  p2->funpublic();                                                                                                                                       
  p3=new child2;                                                                                                                                         
  p3->funpublic();                                                                                                                                       
  return 0;                                                                                                                                              
}                                                                    

运行结果:
这里写图片描述

虚函数

从前面的介绍可知,虽然派生类的成员函数可以覆盖,基类的成员函数,但只能通过对象调用成员函数来使用这种附带功能,根据派生类替换基类对象的原则,可以用基类对象指针指向其派生类对象,然后通过指针调用成员函数,但也无法调用派生类中定义的覆盖函数,为了实现多态性,也就是能够指向派生类的基类指针访问派生类中同名的覆盖成员函数,则应将基类的同名函数声明为虚函数。
虚函数是一种在基类中用virtual加以定义,并在一个或多个派生类中重新定义的成员函数,定义一个虚函数的一般形式为:

virtual<返回类型><函数名>(<形参表>){函数体};

注意:关键字virtual在基类中只使用一次,而在派生类中使用的是重载的函数名,在派生类中,重新定义虚函数是函数的值和参数要和基类中的定义一致否则就属于重载错误.

class Base                                                                                                                                               
{                                                                                                                                                        
  public:                                                                                                                                                
      virtual void funpublic()                                                                                                                            
    {                                                                                                                                                    
      cout<<"基类的成员函数"<<endl;                                                                                                                      
    }                                                                                                                                                    
};                                                                                                                                                       

class child1:public Base                                                                                                                                 
{                                                                                                                                                        
  public:                                                                                                                                                
    void funpublic()                                                                                                                                     
    {                                                                                                                                                    
      cout<<"派生类child1的成员函数"<<endl;                                                                                                              
    }                                                                                                                                                    
};                                                                                                                                                       


class child2:public Base                                                                                                                                 

{                                                                                                                                                        
  public:                                                                                                                                                
    void funpublic()                                                                                                                                     
    {                                                                                                                                                    
      cout <<"派生类child2的成员函数"<<endl;                                                                                                             
    }                                                                                                                                                    
};
int main() {                                                                                                                                             
  Base * p1,*p2,*p3,base;                                                                                                                                

  child1 obj1;                                                                                                                                           
  child2 obj2;                                                                                                                                           
  base =obj1;                                                                                                                                            
  base.funpublic();                                                                                                                                      
  Base  &aliasbase=obj2;                                                                                                                                 
  aliasbase.funpublic();                                                                                                                                 
  p1=&obj1;                                                                                                                                              
  p2=&obj2;                                                                                                                                              
  p1->funpublic();                                                                                                                                       
  p2->funpublic();                                                                                                                                       
  p2=new child1;                                                                                                                                         
  p2->funpublic();                                                                                                                                       
  p3=new child2;                                                                                                                                         
  p3->funpublic();                                                                                                                                       
  return 0;                                                                                                                                              
}                               

结果:
这里写图片描述

猜你喜欢

转载自blog.csdn.net/weibo_dm/article/details/80872826