[疑问]虚函数与多态性

对于普通成员函数的重载,可表达为下面的方式:
 1) 在同一个类中重载
 2) 在不同类中重载
 3)  基类的成员函数在派生类中重载
 因此,重载函数的访问是在编译时区分的,有以下三种方法:

 

1.根据参数的特征加以区分,例如:
         Show(int , char)与Show(char *, float)
     不是同一函数,编译能区分。
 2. 使用“::”加以区分,例如:
           Circle :: Show有别于Point :: Show
  3. 根据类对象加以区分。
           ACircle.Show() 调用Circle::Show()
           APoint.Show() 调用Point :: Show()
   这里ACircle和APoint分别是Circle和Point的对象。

 

 

注意上图,Derived_Class自己定义的成员,P不能访问

 

 

 

#include  <iostream.h>
#include <string.h>
class  B_class
{

  char  name[80];  //默认是私有的吧?!
  public :
  void  put_name(char * s)
   {

    strcpy(name,  s);

  }

  void  show_name( )

  {

    cout<<name<<"\n";

  }

};

 

class  D_class: public B_class
 { 

  char  phone_num[80];
  public:

  void  put_phone(char * num)
  {

    strcpy(phone_num,  num);

  }

   void  show_phone( )

  {

    cout<<phone_num<<"\n";

  }

};

 

main()
 {

  B_class * p;

  B_class B_ob;

  D_class * dp;   

  D_class  D_ob;
  

  p=&B_ob;

  p->put_name("Thomas  Edison");

  p=&D_ob;

  p->put_name("Albert Einstein");

  B_ob.show_name( );
  

  D_ob.show_name( );

  dp=&D_ob;

  dp->put_phone("555555_1234");

  dp->show_phone( );

  p->show_pone( );       //错误

  ((D_class*)p)->show_phone ( );

  p->show_phone( );  //错误

 

 

 

 

  1.可以用一个指向基类的指针指向其公有派生类的对象。但是相反却不正确,即不能用指向派生类的指针指向一个基类的对象。

  2.希望用基类指针访问其公有派生类的特定成员,必须将基类指针用显式类型转换为派生类指针。例如:     ((D_class*)p)->show_phone( );

 

 

5.3.2  虚函数

#include<iostream.h>

class Base

{

  protected:

  int x;

  public:     

  Base(int a)
      {

    x=a;

  }
  void  who()    

  {

    cout<<“base  ”<<x<<“n”;

  }

};

 

class  First_d:  public  Base
{

  public:

  First_d (int  a):Base(a){  }
    void  who()
  {

    cout<<“First derivation ”<<x<“\n”;     //这里的X是什么?

  }
 };

class  Second_d:  public  Base
{

public:
  Second_d (int  a):Base(a){  }    
  void  who()
  {

    cout<<“Second derivation ”<<x<“\n”;

  }
};           

 

void main()
 {  

   Base * p;
   Base      base_obj(1);
   First_d        first_obj(2);
   Second_d    second_obj(3);
   p=&base_obj;
   p->who();
   p=&first_obj;
   p->who();
   p=&second_obj;
   p->who();    
   first_obj.who();
   second_obj.who();

}

 指向基类的指针p,不管是指向基类的对象base_obj还是指向派生的对象first_obj和second_obj, p->who()调用的都是基类定义的 who()的版本.必须显式地用
               first_obj.who();
  和
              second_obj.who();
    才能调用类first_d和类second_d中定义的who()的版本。其本质的原因在于普通成员函数的调用是在编译时静态区分。

 

 

 

 

 

 

 

 

例 5-31
#include <iostream.h>
class  figure
{

 protected:
     double  x,  y;
  public:
    void  set_dim(double i, double j=0)
    {

      x=i; 

      y=j;  

   }
    virtual  void  show_area()
    {

      cout<<“No area computation  defined”;        
        cout<<“for this class.\n”;

   }

}; 

 

class  triangle :   public  figure
{

public:
    void show_area()
    {

        cout<<“Triangle  with high”;
          cout<<x<<“and base”<<y;
          cout<<“  has an area of”;
        cout<<x*0.5*y<<“\n”;  

   }

};

 

class  square  :   public  figure
{

public:
  void  show_area()
   {

    cout<<“Square  with dimension”;
        cout<<x<<“*” <<y;
        cout<<“has an area of”;
        cout<<x * y<<“\n”;

  }

};    

 

class  circle  :  public figure
 {

 public:
     void show_area()
     {

        cout<<“Circle with radius” ;
         cout<<x;
         cout<<“has  an aera of” ;
         cout<<3.14* x*x;
      }
  };

 

上图中首先调用基类对象中的函数set_dim(int,int),设置的x,y可以在派生类中可见吧???然后是基类调用派生类对象中的函数show_area()

 

上面的倒数第二行,Bref.fun()是调用class C中的fun()吗? ???这里的Bref是B的引用,又不是指针!

 

posted @ 2012-04-06 20:40  carbs  阅读(320)  评论(0编辑  收藏  举报