C++将子类转换为基类



使用以下类:

enum class OBJECT_TYPE {TYPE_1, TYPE_2, TYPE_3};
class BaseClass {
public:
BaseClass();
virtual ~BaseClass();
OBJECT_TYPE getObjectType() { return m_objectType; }
protected:
OBJECT_TYPE m_objectType;
}
class ChildClass : public BaseClass {
public:
ChildClass();
virtual ~ChildClass();
virtual void init() = 0;
protected:
// some other variables
}
class ChildChildClass : public ChildClass {
public:
ChildChildClass ();
~ChildChildClass ();
void init() override { m_objectType = OBJECT_TYPE::TYPE_3 }
private:
// some other variables
}

在代码库的另一部分中,我如何将void*强制转换为ChildChildClass实例,然后再将BaseClass*强制转换为实例,这样我就可以调用getObjectType()来确定它指向的对象类型

(someOtherMethod()ChildChildClass返回void*(

void* initialPointer = someOtherMethod();
BaseClass* basePointer = static_cast<BaseClass>(initialPointer);
if (basePointer->getObjectType() == OBJECT_TYPE::TYPE_3) {
ChildChildClass* childChildPointer = static_cast<ChildChildClass*>(basePointer);
}

我想我在使用继承时可能误解了投射指针,因为我得到了返回的objectType的无意义值,所以任何建议或信息都将不胜感激!

我将忽略此类设计的众多问题,只假设您有一个非常的充分理由(即无法更改设计(想要做您想要做的事情。如果您知道CCD_ 9返回指向CCD_ 11对象的CCD_,那么您可以首先将static_castvoid*转换为ChildChildClass*,然后执行到BaseClass*的显式上变频,或者仅将该ChildChildClass*用作BaseClass*,因为它可以以任何方式隐式转换(不需要仅为了调用该方法而执行上变频,因为ChildChildClass是从BaseClass公开派生的(:

ChildChildClass* initialPointer = static_cast<ChildChildClass*>(someOtherMethod());
BaseClass* basePointer = static_cast<BaseClass*>(initialPointer);

然而,基于您上面的代码,我相信您实际上并不知道someOtherMethod()返回指向ChildChildClass对象的指针。否则,为什么要在转换为ChildChildClass*之前检查它是否存在?如果您不知道someOtherMethod()返回的void*指向的对象的具体类型,那么就无法在此处执行您想要执行的强制转换(因为有一种已知的方法可以知道实际应该将什么强制转换为什么(。一种解决方案是将someOtherMethod()更改为始终返回一个BaseClass*或至少返回一个您确信始终指向BaseClass对象的void*

您应该使用reinterpret_cast<>void*:进行投射

BaseClass* basePointer = reinterpret_cast<BaseClass*>(initialPointer);

但要格外小心!如果initialPointer没有指向正确类型的对象,这就是UB!

其他建议:

对于下铸,更安全的方法是使用dynamic_cast<>:

ChildChildClass* childChildPointer = dynamic_cast<ChildChildClass*>(basePointer);
if (! childChildPointer) 
cout << "Something wrong happened !" <<endl; 

我建议使用dynamic_cast

// This is risky but I assume you know what you are doing.
// BTW, you are using static_cast<BaseClass>. That is not correct.
BaseClass* basePointer = static_cast<BaseClass*>(initialPointer);
// Now use dynamic_cast.
ChildChildClass* childChildPointer = dynamic_cast<ChildChildClass*>(basePointer);
if ( childChildPointer != nullptr)
{
// Use childChildPointer.
}
else
{
// Do something different.
}

如果CCD_ 34可以被修改为返回CCD_。

BaseClass* basePointer = someOtherMethod();

那么,代码的其余部分不太可能成为问题。

最新更新