SmartPtr cast down: Conversion from a virtual base class is implied

Hey guys! I have this kind of class inheritance:

31678-пвапфвап.png

I am using Unreal’s SharedPtrs all around to work with objects of this class. At some point, I have this kind of code:

// Cast armor itemstats to EArmorStats to reveal durability info
auto armor = StaticCastSharedPtr<EArmorStats>(ArmorSlot->getStats()).ToSharedRef();

getStats() returns TSharedPtr of EternalStats , so I am casting down from EternalStats to EArmorStats. It is not super-safe, but should work properly. However I get an error:

cannot convert a 'EternalStats*' to a 'EArmorStats*'; conversion from a virtual base class is implied

So, is it because of virtual inheritance? As far as I recall, I used virtual inheritance in this case because of diamond problem (I inherit one more class from EternalStats and then inherit another class from both these classes).

Hi,

This is a general C++ problem, as opposed to a UE4 problem:

Perhaps you need to reconsider your class hierarchy.

Steve

Yeah, that’s what I was afraid of. But what if I “strip” the object out of smart ptr into the naked pointer and then do dynamic_cast? I know for sure that the pointer points to child class’s object. How bad is such code? :slight_smile:

It’s not our place to judge the needs or quality of your code. :slight_smile:

dynamic_cast may be an option for you but you will have to turn on RTTI which will have a large impact on the code footprint of your project.

In the interests of simplicity and memory, it may be easier to just add a virtual getter to your virtual base:

class EArmorStats;

class EternalStats
{
    // ...

    virtual EArmorStats* GetArmorStats()
    {
        return nullptr;
    }
};

class DerivedClass : public EArmorStats, EOtherArmorStatsDerivedClass
{
    virtual EArmorStats* GetArmorStats() override
    {
        return this;
    }
};

It’s not nice, but diamond inheritance doesn’t usually give you much opportunity for niceness.

Steve

Thanks a lot, that makes sense :slight_smile: