使用以下类:
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_cast
、void*
转换为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();
那么,代码的其余部分不太可能成为问题。