多态的一个特殊例子

我们先回复一下多态,看下面一个例子
#include "stdafx.h"
class A1
{
public:
 virtual void sample(int a,int b)=0;

};
class B1 :public A1
{
public:
virtual void sample (int a,int b){trace(“class B1:: sample”);};
  
};

class C1:public A1
{
public:
virtual void sample (int a,int b){ trace(“class C1:: sample”);};
};

int main(int argc, char* argv[])
{
 A1 a1,a2;
 B1 b1
 C1 c1;
a1=&b1;
a2=&b2;

/
a1->sample(2,3);
 a2->sample(1,3);
    //
 
 return 0;
}
根据多态的特性a1->sample(2,3)调用的实际上是class B1:: sample
              a2->sample(2,3)调用的实际上是class C1:: sample
这是一个最经典的多态的例子了,这里我们不做过多解释!

自以为对多态有了很深的了解,但是下面这个例子起初使我一头雾水,”自高”的心态也就瓦解了,但总算功夫不负有心头人,总算搞清楚原因了,先看看这个例子!


#include "stdafx.h"
class A1
{
public:
 virtual void sample(int a,int b){};

};
class B1
{
 public:
  
  virtual void sample1(int a,int b){};
  virtual void sample2(int a,int b){};
  virtual void sample3(int a,int b){};
};

class C1:public A1,public B1
{
public:

 
 virtual void sample2(int a,int b){};
 virtual void sample1(int a,int b){};
 
 virtual void sample(int a,int b){};
 
void setA1(void** a){*a=(A1*)this; }
 void setB1(void** b){*b=(B1*)this; }
};

int main(int argc, char* argv[])
{
 A1 *a1,*b2;
 
 C1 c1;
c1.setA1((void**)&a1);
 c1.setB1((void**)&b2);
 
 a1->sample(2,3);
 b2->sample(1,3);
 
 return 0;
}
  按照经典的例子看a1->sample(2,3); b2->sample(1,3);这个两个调用的应该都是class C1:: sample(),令人遗憾的是a1->sample(2,3)是我们所希望看到的调用class C1:: sample(),而b2->sample(1,3);调用的却是class C1:: sample1(),这是为什么那!
下面就是我跟踪DEBUG看到的结果

图1

根据上图!原因也就一幕了然了!
调用c1.setA1((void**)&a1);的时候,因为类CA1的原结构中虚函数表中就一项,这时候通过
*a=(A1*)this;的赋值过程,使得CA1的指针a1指向的就是c1中子对象A1虚函数表中的c1::sample(int,int).

调用c1.setB1((void**)&b1);的时候,因为类CA1的原结构中虚函数表中就一项,这时候通过
*a=(B1*)this;的赋值过程, 使得CA1的指针b1指向的就是c1中子对象B1虚函数表中第一项c1::sample1(int,int),其它的表项也就同时被切割掉了,这就解释了为什么b2->sample(1,3)为什么会转到c1::sample1(int,int)的不解了!也就是说这种情况下的赋值只有c1中子对象B1虚函数表中的第一项才被复制给b1指针!!

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值