编程小技巧

    返回首页    发表留言
本文作者:李德强
          技巧十七:对象和对象指针转换
 
 

        今天跟大家分享的小技巧是关于对象和对象指针类型转换的,我们在这里所说的对象是指C++中的对象,而C++中的对象指针才是Java中的对象。如有学习Java的朋友请参见我们所说的对象指针。

 

        一、对象的类型转换:

        我们假设有这样两个类:

class A
{
	public:
		int i;
};
class B: public A
{
	public:
		B()
		{
			this->i = 0;
			this->j = 0;
		}
		B(A &a)
		{
			this->i = a.i;
			this->j = 0;
		}
		int j;
};
int main(void)
{
	B b1;
	b1.i = 1;
	b1.j = 2;
	A a1 = (A) b1;
	B b2 = B(a1);
	return 0;
}

        我们把类B的对象b1强制转换为A类的对象a1时,无需做其它处理,因为B是类A的子类,由类的继承关系我们知道父类中所包含的属性一定不少于子类,即便父类中的成员变量可能是私有的,所以将b1强制转为a1是没有问题的,在转换之后a1中的属性值即为b1中继承A类的值。

        而对于把A类的对象a1,强制转换为B类的对象b2时,就有一点麻烦了,在C++中如果一个父类的对象想要转为子类的对象时,由于子类中的属性可能多于父类的属性,所以对于子类来说,那些在子类中存在而在父类中不存在的属性没有办法进行初始化,所以在一个父类的对象想要转为子类的对象时必须要在子类中编写一个“拷贝构造函数”在a1强制转换为b2时(B b2 = (B)a1; ),其实是调用了B类中的拷贝构造函数,所以这样使用也是安全的。

 

        二、对象指针的类型转换:

        还是上面那两个类A和B,我们进行如下的处理:

int main(void)
{
	B* b1 = new B();
	b1->i = 1;
	b1->j = 2;
	A* a1 = (A*) b1;
	B* b2 = (B*) a1;
	delete(b1);
	return 0;
}

        对于对象指针类型的转换就非常容易理解了,当执行new B()语句时,事实上程序是在堆内存中向系统申请了个连续的内存区域,它包含8个字节,也就是变量i和j,而对于A *a1、B *b1和B *b2这三个指针变量来说,它们都是对象指针,所指向的内存地址也是相同的,都是刚刚申请的内存区域。这三个指针在内存中的关系是这样的:

        可见a1、b1、b2它们所指向的内存是相同的,而对于a1来说,它是一个A类的对象指针,所以对a1而言它只能访问并使用它内部的属性int i;而b1和b2都是B类的对象指针,对于b1和b2而言它们可以访问父类中的属性int i和自身类中的属性int j。所以对于指向这个对象地址的指针来说,无论做什么样的类型转换,只要最后将其转为B类的对象指针,结果就是没有任何问题的,比如如下的转换:        

B* b1 = new B();
A* p0 = (A*) b1;
int* p1 = (int*) p0;
void* p2 = (void*) p1;
B* b2 = (B*) p2;
delete (b1);

        也就是说,对于对象指针来说,指针的类型决定了它所能够访问对象属性的范围,而对象真正所占用的内存区域取决于它在创建时所构建的类型。

        当然,在C++中还有4个关键字来做专门的类型转换处理,它们分别是:const_cast、static_cast、dynamic_cast、reinterpret_cast。如果你对基本类型、对象类型和对象指针类型的转换都有所了解,那么这4种专门为类型转换所准备的关键字就更好解理了,不但知道使用它们之后运行结果是什么,而且也会对其原理有所了解,对于C++的这4种类型转换我们就不在赘述了,这方向的资料请朋友们自己学习。

 

        今天的小技巧你学会了吗?

 

    返回首页    返回顶部
  看不清?点击刷新

 

  Copyright © 2015-2018 问渠网 辽ICP备15013245号