如何将基类指针数组强制转换为派生类

How to cast array of base class pointer to derived class

本文关键字:转换 派生 数组 基类 指针      更新时间:2023-10-16

我们如何将基类指针数组强制转换为派生类指针数组。下面的代码显示了我正在尝试执行的操作的简单示例:

class CBaseClass
{
public :
int CommonValue;
};
class CFirstItem : public CBaseClass
{
public :
int firtValue;      
};
class CSecondItem : public CBaseClass
{
public :
int secondValue;        
};
class CThirdItem : public CBaseClass
{
public :
int thirdValue;     
};

class Manager
{
public :
Manager()
{
for (unsigned int index = 0; index < 5; ++index)
{
m_firstItem[index] = new CFirstItem();
}
for (unsigned int index = 0; index < 10; ++index)
{
m_secondItem[index] = new CSecondItem();
}
for (unsigned int index = 0; index < 12; ++index)
{
m_thirdItem[index] = new CThirdItem();
}
}
private :
CBaseClass* m_firstItem[5];
CBaseClass* m_secondItem[10];   
CBaseClass* m_thirdItem[12];    
};

我在这里的主要问题是我如何从CBaseClass投射到CFirstClassCSecondClass,我尝试过

CFirstClass* wFirstClass = static_cast<wFirstClass*>(m_firstItem);

这似乎行不通,有什么办法可以制作这个演员表吗?

CFirstClass* wFirstClass = static_cast<wFirstClass*>(m_firstItem);

是错误的,因为w_firstItem在上面的表达式中衰减到CBaseClass**

如果你能设计你的程序,这样你就不需要投射了,你会过得更好。如果必须强制转换,则需要使用dynamic_cast.

CFirstClass* wFirstClass = dynamic_cast<CFirstClass*>(m_firstItem[0]);
if ( wFirstClass )
{
// Use the pointer.
}
else
{
// Deal with other cases
}

如果需要在m_firstItem中投射每个指针,则需要使用循环。

for ( auto item : m_firstItem )
{
CFirstClass* wFirstClass = dynamic_cast<CFirstClass*>(item);
if ( wFirstClass )
{
// Use the pointer.
}
else
{
// Deal with other cases
}
}

更新

@RemyLebeau提出了一个很好的观点。仅当m_firstItem包含指向不同子类型的CBaseClass的指针时,才应使用dynamic_cast。在您发布的代码中,由于它只包含指向CFirstClass的指针,因此可以使用static_cast而不是dynamic_cast

CFirstClass* wFirstClass = static_cast<CFirstClass*>(m_firstItem[0]);

循环版本同样可以使用static_cast<CFirstClass*>(item)

不能简单地将基指针数组类型转换为派生指针数组。 指针不会指向正确的地址。 如果你需要一个派生指针数组,你必须创建一个单独的数组并正确地对源项进行类型转换,例如:

CFirstClass* wFirstClass[5];
for (int i = 0; i < 5; ++i)
wFirstClass[i] = static_cast<CFirstClass*>(m_firstItem[i]);

与其他数组相同:

CSecondClass* wSecondClass[10];
for (int i = 0; i < 10; ++i)
wSecondClass[i] = static_cast<CSecondClass*>(m_secondItem[i]);

CThirdClass* wThirdClass[12];
for (int i = 0; i < 12; ++i)
wThirdClass[i] = static_cast<CThirdClass*>(m_thirdItem[i]);