在一个复杂的代码库中,我有一个指向非虚基类指针的数组(基类没有虚方法)。
考虑下面的代码:
输出结果为(使用Mingw-w64 GCC 4.9.2在Win64上编译):
失败的原因是每个TVirtualDerived实例都有一个指向虚拟表的指针,而TBase没有。因此,在没有先前类型信息的情况下(从void*到TBase*),向上转型为TBase不安全。
问题在于我一开始无法避免强制转换为void*。在基类中添加一个虚方法(例如析构函数)可以解决问题,但会增加内存成本(我想要避免这种情况)
背景:
我们正在一个非常受限制的环境(内存严重受限)中实现信号/槽系统。由于我们有数百万个可以发送或接收信号的对象,因此这种优化是有效的(当然,只有在它起作用时)
问题:
如何解决这个问题?到目前为止,我已经找到了以下解决方法:
1- 在TBase中添加一个虚方法。虽然可行,但并没有真正解决问题,只是避免了问题。而且效率低下(太多内存)
2- 代价是失去通用性,将数组转换为TBase*而不是void*。(可能是我下一步尝试的方案)
您看有其他解决方案吗?
考虑下面的代码:
#include <iostream>
using namespace std;
class TBase
{
public:
TBase(int i = 0) : m_iData(i) {}
~TBase(void) {}
void Print(void) {std::cout << "Data = " << m_iData << std::endl;}
protected:
int m_iData;
};
class TStaticDerived : public TBase
{
public:
TStaticDerived(void) : TBase(1) {}
~TStaticDerived(void) {}
};
class TVirtualDerived : public TBase
{
public:
TVirtualDerived(void) : TBase(2) {}
virtual ~TVirtualDerived(void) {} //will force the creation of a VTABLE
};
void PrintType(TBase *pBase)
{
pBase->Print();
}
void PrintType(void** pArray, size_t iSize)
{
for(size_t i = 0; i < iSize; i++)
{
TBase *pBase = (TBase*) pArray[i];
pBase->Print();
}
}
int main()
{
TBase b(0);
TStaticDerived sd;
TVirtualDerived vd;
PrintType(&b);
PrintType(&sd);
PrintType(&vd); //OK
void* vArray[3];
vArray[0] = &b;
vArray[1] = &sd;
vArray[2] = &vd; //VTABLE not taken into account -> pointer not OK
PrintType(vArray, 3);
return 0;
}
输出结果为(使用Mingw-w64 GCC 4.9.2在Win64上编译):
Data = 0
Data = 1
Data = 2
Data = 0
Data = 1
Data = 4771632
失败的原因是每个TVirtualDerived实例都有一个指向虚拟表的指针,而TBase没有。因此,在没有先前类型信息的情况下(从void*到TBase*),向上转型为TBase不安全。
问题在于我一开始无法避免强制转换为void*。在基类中添加一个虚方法(例如析构函数)可以解决问题,但会增加内存成本(我想要避免这种情况)
背景:
我们正在一个非常受限制的环境(内存严重受限)中实现信号/槽系统。由于我们有数百万个可以发送或接收信号的对象,因此这种优化是有效的(当然,只有在它起作用时)
问题:
如何解决这个问题?到目前为止,我已经找到了以下解决方法:
1- 在TBase中添加一个虚方法。虽然可行,但并没有真正解决问题,只是避免了问题。而且效率低下(太多内存)
2- 代价是失去通用性,将数组转换为TBase*而不是void*。(可能是我下一步尝试的方案)
您看有其他解决方案吗?
TBase*
,再转换为void*
,这样能否满足您的需求?(请参见此处) - danielschemmelTBase
里有1000个int
,这仍然不起作用。 - BarryTBase
中添加成员函数TBase* operator&() { return this; }
(以及其const
版本)。 - celtschk