VS2005中派生模板类的BUG

1 篇文章 0 订阅
1 篇文章 0 订阅

一般来说犯错误的都是开发者.VS的错误还是蛮少的.额..除了预编译头有时候会错误要Clean一下.

今天确实遇到了一个bug.查了半天.又写了好些测试代码.才把错误模型整理出来.

发现是在存在虚函数表时对于父类模板类的偏移计算错误.这句话说的挺绕口.

据说也和VS对代码限制较少有关.在GCC下是编译不过去的.


模型挺简单

template< class T >
class TestTClass
{
public:
	T	i;
	std::vector<T>	m_vec;
	T GetNumber()
	{
		return i;
	}

	int GetSize()
	{
		return m_vec.size();
	}
};

class TestClass : public TestTClass<int>
{
public:
	TestClass()
	{
		i = 1;
	}

	int GetNumber()
	{
		return TestTClass::GetNumber();
	}

	int GetSize()
	{
		return TestTClass::GetSize();
	}
};

这段代码中TestClass从TestTClass派生.并重写了两个函数.没有虚函数.这时没问题.测试代码

	TestClass	kClass;
	kClass.i = 3;
	kClass.m_vec.push_back( 1 );
	int iTest = kClass.GetNumber();
	int iSize = kClass.GetSize();


此时的iTest等于3. iSize等于1;


但如果将GetSize改成虚函数.

class TestClass : public TestTClass<int>
{
public:
	TestClass()
	{
		i = 1;
	}

	int GetNumber()
	{
		return TestTClass::GetNumber();
	}

	virtual int GetSize()
	{
		return TestTClass::GetSize();
	}
};

问题就出来了.此时跟踪到TestTClass::GetNumber函数中发现this指针与父类的This指针已经不一样了.整个内存已经乱了.i和m_vec已经和父类不是同一个i和m_vec了.

	TestClass	kClass;
	kClass.i = 3;
	kClass.m_vec.push_back( 1 );
	int iTest = kClass.GetNumber();
	int iSize = kClass.GetSize();

此时的iTest和iSize大概都等于0;


如果是虚继承的话 like this:

class TestClass : virtual public TestTClass<int>
又没有问题.

根据现象分析.虚继承时父类包含有指向子类的指针.地址已经固定了.所以正确.由此推断可能是由于根据虚函数表计算子类地址时有错误.


但有一点必须指出.

return TestTClass::GetNumber();
这样的写法是不严谨的写法.由于TestClass是模板.模板是编译器生成代码的.按道理必须指定类型.如果没有类型.生成的子类又是指向哪里呢?

假如写法都写成

return TestTClass<int>::GetNumber();
这样就不会发生这样的问题.据说GCC像上边的写法是编译不过去的.





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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值