c++指针比较的含义

  在c++中,一个对象可以有多个有效地地址,因此,指针比较并不是关于地址问题,而是关于类的判别 (object identity)。

   class Shape {.......};

   class Subject {.........};

   class ObservedBlob :public shape , public Subject {.........};

   在这个类的继承层次结构中,ObservedBlob 只是由shape和Subject派生而来,并且都是公有继承,因此存在从派生类对象到任何基类的预定义转换。


    ObservedBlob *obj=new ObservedBlob; 

    Shape * s=obj;              //发生预定义转换

    Subject * subj=obj;       //发生预定义转换

  

   The availability of these conversions means that a pointer to anObservedBlob may be compared to a pointer to either of its base classes.

    if( ob == s ) ...
    if( subj == ob ) ...

    In this case, both of these conditions will be true even if the addresses contained inob,s, andsubj differ. Consider two possible memory layouts for theObservedBlob object to which these pointers refer, as shown inFigure 7.

 

    多重继承情形下两种可能的内存排列。不管是哪一种排列,对象都具有多个地址。

    第一种排列中,s和subj都指向对象ob内的Shape和Subject子对象,他们指向的地址与对象ob所在的地址不同。


    在第二种排列中,s和对象ob恰好具有相同的地址。

#include <iostream>
using std::cout;
using std::endl;
class Shape
{
public:  
	Shape(){cout<<"Base class-Shape is Constructed"<<endl;}  
	virtual ~Shape(){cout<<"Base class-Shape is deconstructed"<<endl;}  
	virtual void Clue(){cout<<"this is a member function in Shape"<<endl;}  
};


class Subject 
{
public:  
	Subject (){cout<<"Base class-Subject is Constructed"<<endl;}  
	virtual ~Subject (){cout<<"Base class-Subject is deconstructed"<<endl;}  
	virtual void Play(){cout<<"this is a member function in Subject"<<endl;}  
};

class ObservedBlob :public Shape , public Subject
{
public:
	ObservedBlob(){cout<<"Derived class is Constructed"<<endl;}  
	~ObservedBlob(){cout<<"Derived class is deconstructed"<<endl;}  
	void Clue(){cout<<"this is a member function in ShapeDerived"<<endl;}  
	void Play(){cout<<"this is a member function in SubjectDerived"<<endl;}  
};

void main()  
{  
	ObservedBlob *ob=new ObservedBlob;
	cout<<endl<<"ob的内存地址:   "<<ob<<endl;
	Shape* s=ob;
	Subject* subj=ob;
	s->Clue();
	cout<<endl<<"s的内存地址:    "<<s<<endl;
	subj->Play();
    cout<<endl<<"subj的内存地址: "<<subj<<endl;
	ob->Clue();  
	ob->Play();
	delete ob; 
	getchar();
}  


执行结果:



   不管是那种排列,ob 、s、subj都指向同一个ObservedBlob对象,编译器为了确保

    if( ob == s ) ...
    if( subj == ob ) ...

表达式的正确性,编译器将通过指针的偏移量的运算来完成指针的比较,例如下面的表达式:

   ob == subj

may be (loosely) translated as

  ob ? (ob+delta == subj) : (subj == 0)
delta是Subject子对象在ObservedBlob对象中的偏移量。 换句话说的话,就是假如ob是空指针,subj也就是空指针(因为    Subject * subj=obj;);否则ob将通过与偏移量delta相加,实现变为一个指向ob对象内Subject基类子对象的指针的转换,再与subj相比较。

 

  其实,不能看出,一般而言,我们在处理一个对象指针或者引用时,要注意避免类型信息的丢失。

 当用对象的指针赋值给void指针时,会导致对象类型信息丢失。


转载于:https://www.cnblogs.com/javaspring/archive/2011/12/16/2656166.html

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值