C/C++日常学习总结(第十四篇)C++基类与派生类的转换

        在学习完虚函数后,最深的影响就是根据所指对象的类型,判断调用基类还是派生类中的函数,所以又产生了一个困惑。

看代码:

class A1
{ 
public:
    virtual void print(void) 
   { 
     cout<<"A::print()"<<endl; 
   } 
};

class B:public A1
{ 
public:
   virtual void print(void) 
  { 
    cout<<"B::print()"<<endl;

  }}; 
class C:public B
{
public:
   virtual void print(void) 
  {
    cout<<"C::print()"<<endl; 
  }
}; 
void print(A1 *a) 
{ 
 a->print();
}
void print1(A1 a) 
{ 
 a.print();
}


在main函数中执行:


 A1 a, *pa,*pb,*pc;
 B b;
 C c;
 pa=&a; 
 pb=&b; 
 pc=&c; 
 a.print();
 b.print(); 
 c.print(); 

 pa->print(); 
 pb->print();
 pc->print();

 A1 d = c;
 d.print();

 print1(a); 
 print1(b); 
 print1(c); 


大家可以先不运行,自己思考下结果。我所疑问的就是最后下面的5行代码,为什么执行结果都是A::print().

 

 

原因:和普通函数一样,虚函数一样可以通过对象名来调用,此时编译器采用的是静态联编。


           通过对象名访问虚函数时, 调用哪个类的函数取决于定义对象名的类型。对象类型是基类时,就调用基类的函数;对象类型是子类时,就调用子类的函数。

 

参考链接:http://see.xidian.edu.cn/cpp/biancheng/view/239.html

原理解释:

          基类与派生类对象之间有赋值兼容关系,由于派生类中包含从基类继承的成员,因此可以将派生类的值赋给基类对象,在用到基类对象的时候可以用其子类对象代替。
         1) 派生类对象可以向基类对象赋值

             可以用子类(即公用派生类)对象对其基类对象赋值。如
            A a1;  //定义基类A对象a1
            B b1;  //定义类A的公用派生类B的对象b1
            a1=b1;  //用派生类B对象b1对基类对象a1赋值
            在赋值时舍弃派生类自己的成员。也就是“大材小用”,如图11.26所示。

实际上,所谓赋值只是对数据成员赋值,对成员函数不存在赋值问题。

 

2) 如果函数的参数是基类对象或基类对象的引用,相应的实参可以用子类对象。

如有一函数:
    fun: void fun(A& r)  //形参是类A的对象的引用变量
    {
        cout<<r.num<<endl;
    }  //输出该引用变量的数据成员num
函数的形参是类A的对象的引用变量,本来实参应该为A类的对象。由于子类对象与派生类对象赋值兼容,派生类对象能自动转换类型,在调用fun函数时可以用派生类B的对象b1作实参:
     fun(b1);
输出类B的对象b1的基类数据成员num的值。

与前相同,在fun函数中只能输出派生类中基类成员的值。

 

 

这也就能解释上面的输出结果了。

          

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值