Search code examples
c++multiple-inheritance

C++ Cast sub-sub class to base


With the classes below:

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
}

In a separate part of the code base, how would I cast a void* to a ChildChildClass instance to a BaseClass* such that I can call getObjectType() to determine which type of object it points to. I'm currently doing this:

(someOtherMethod() returns a void* to a ChildChildClass)

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

I think I may be misunderstanding casting pointers when using inheritance, as I'm getting nonsense values for the returned objectType so any advice or info would be appreciated!


Solution

  • I'll ignore the numerous issues with such a design and just assume that you have a very good reason (i.e. can't change the design) for wanting to do what you're asking for. If you know that someOtherMethod() returns a void* that points to a ChildChildClass object, then you can first static_cast that void* to a ChildChildClass* and then either perform an explicit upcast to a BaseClass* or just use that ChildChildClass* as a BaseClass* since it can implicitly be converted anyways (there should be no need to perform an upcast just for the purpose of calling the method since ChildChildClass publicly derives from BaseClass):

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

    However, based on your code above, I am led to believe that you don't actually know that someOtherMethod() returns a pointer to a ChildChildClass object. Otherwise, why would you have to check whether it does before casting to ChildChildClass*? If you don't know the concrete type of object that the void* returned by someOtherMethod() points to, then there is no way to perform the cast you want to perform here (because there is know way of knowing what should actually be cast into what). One solution would be to change someOtherMethod() to always return a BaseClass* or at least a void* that you know for sure always points to a BaseClass object…