多重继承与void*指针转换问题的分析

C++支持多重继承,然而多重继承可能会导致一些奇怪的问题,我前段时间遇到一个指针转换问题,非常典型。

先看一个简单的测试代码:

强制转换为void* 先static_cast再强制转换为void* 先dynamic_cast再强制转换为void*

#include <iostream>
using namespace std;

class IA
{
public:
	virtual ~IA(){}
	virtual void a() = 0;
};

class IB
{
public:
	virtual ~IB(){}
	virtual void b() = 0;
};

class CMulti : public IA, public IB
{
public:
	CMulti(){}
	~CMulti(){}

	void a(){ cout << "C::a()" << endl; }
	void b(){ cout << "C::b()" << endl; }
};

void testCastA(void *p)
{
	cout << "cast from void*(" << p << ")to IA*:  ";
	IA *a = (IA *)p;
	a->a();
}

void testCastB(void *p)
{
	cout << "cast from void*(" << p << ")to IB*:  ";
	IB *b = (IB *)p;
	b->b();
}


int _tmain(int argc, _TCHAR* argv[])
{
	CMulti * c = new CMulti;

	cout << "cast to void*, then to IA or IB:" << endl;
	testCastA((void*)c);
	testCastB((void*)c);
	cout << endl;

	cout << "static_cast to void*, then to IA or IB:" << endl;
	testCastA((void*)static_cast<IA*>(c));
	testCastB((void*)static_cast<IB*>(c));
	cout << endl;

	cout << "dynamic_cast to void*, then to IA or IB:" << endl;
	testCastA((void*)dynamic_cast<IA*>(c));
	testCastB((void*)dynamic_cast<IB*>(c));

	return 0;
}

1111

差异很明显了,结论也很明了:多重继承时,子类指针转换为非第一继承的父类指针时,会发生地址偏移(注意图上标红的部分)。这是因为每一个父类都会占用 4 个字节维护自己的虚函数表。所以,当 CMulti* 转换为 IB* 时,指针加 4 ,因为 IA 是 CMulti 的第一父类, IB 是第二父类,依次类推……

如果我们在某些地方不得不使用 void* 来进行代码适配时,遇到多重继承就要注意这一点,否则很可能你调用的是 b() 方法,实际执行的是 a() ,达导致异常甚至崩溃。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值