C++ 对象切割(Object slicing )与虚拟函式 [大三TJB_708]

1 对象切割(Object slicing)

一般来说,衍生类所占的存储空间一般都比基础类大。当用基础类强制转换派生类物件(对象)指標时就会产生对象切割(Object slicing)。

 

2 举例子

class CObject
{
  public:
	virtual void vfunc(){cout << "CObject:vfunc\n";}
};

class CObject1 : public CObject
{
  public:	
	int m_data1;
	void fun()
	{	cout << "CObject1:fun \n";
		vfunc();
	}	
	virtual void vfunc(){
		cout << "CObject1:vfunc \n";
	}
};

class CObject2 : public CObject1
{
  public:
	int m_data2; 
	virtual void vfunc()
	{
		cout << "CObject2:vfunc \n";
	}
};

void main()
{
	CObject2 myobject; 
	CObject2 *mypobject = new CObject2;
	
	//--------------test1---------- 
	myobject.fun();
	
	//--------------test2---------- 
	((CObject1*)(&myobject))->fun();
	
	//--------------test3---------- 
	mypobject->fun();

	//--------------test4---------- 
	((CObject)myobject).fun();
}

 

<pre>
程序运行结果如下:



CObject1:fun
CObject2:vfunc
CObject1:fun
CObject2:vfunc
CObject1:fun
CObject2:vfunc
CObject1:fun
CObject:vfunc
因为只有CObject1类具有fun函数,所以所有的调用都是调用CObject1内的fun函数,根据虚拟函数的妙用( http://blog.csdn.net/misskissc/article/details/8544056)可知,当每个物件(对象)调用函数时都是调用对象所对应类中所定义的函数。根据执行结果,只有最后一个结果略显不同,其实最后一个结果经历了对象切割。
 

3对象切割

其实test4所经历的过程如下

图1.对象切割图示
当我们呼叫
((CObject)myobject).fun();
myobject已经是被切割了。编译器在此语句为传值的方式下把CObject1物件内的内容拷贝了一份,使myobject的vtable内容与CObject1物件的vtable内容一样。所以,程序中的test4调用的虚拟函式为CObject1物件的vtable中的对应的虚拟函式。

此次笔记记录完毕。

你可能感兴趣的:(C++ 对象切割(Object slicing )与虚拟函式 [大三TJB_708])