Download

c++ polymorphism Problem

Hello. I’m working with Unreal Engine 4.18.1 and Visual Studio 2015. I have some code in C++ and some problems when I want to do polymorphism.

I have myItems.h



UCLASS()
class MYPROJECT5_API AmyItems : public AActor
{

    GENERATED_BODY()



public:
    AmyItems();

    void Init();


    AMyProject5Character* CharacterRef2;

    //The texture ID from the main texture to draw
    FVector2D uvInTexture[2];
    unsigned int itemSlotSize;

    UPROPERTY(VisibleAnywhere, BluePrintReadWrite, Category = "item_id", meta = (AllowPrivateAccess = "true"))
    int ID;

    class UTexture2D* texture;
    virtual void useItem();

    /** called when projectile hits something */


};



and healthPotion,h



class MYPROJECT5_API healthPotion : public AmyItems
{
public:
    UFUNCTION()
    void useItem() override;
    unsigned int power;
    UPROPERTY(VisibleDefaultsOnly, Category = Mesh)
    class UStaticMeshComponent* potion_mesh;
    void Init();
    int ID;
    healthPotion();
    ~healthPotion();
};



So basically I want to derive from myItems class and overwrite the useItem() function so it can be applied in particular for every object (like the health class increases the health, the mana increases the mana etc … )

And when Im doing a test in the HUD class:



AmyItems *itemsA[2];

...

itemsA[0] = GetWorld()->SpawnActor<healthPotion>(healthPotion::StaticClass(), SpawnLocation, SpawnRotation, ActorSpawnParams);
itemsA[1] = GetWorld()->SpawnActor<manaPotion>(manaPotion::StaticClass(), SpawnLocation, SpawnRotation, ActorSpawnParams);


...
itemsA[0] and itemsA[1] witch are base class pointers point to child class pointers but they access the base members instead of child members


itemsA[0]->useItem() actually calls AmyItems->useItem() instead of healthPotion->useItem();



Thanks.

Do you have Super::useItem(); in your mana and health potion useItem functions? That will actually call the function of the parent class (AnyItems) in addition to whatever code comes after it. Maybe that’s what’s causing the confusion?

Would be easier to tell if you also posted the useItem() function code for each class.

When I use Super::useItem() the it actually calls the code from the AActor class witch is the main base class…instead of the AmyItems…and that function does not exists and it shows an error.

Try adding “virtual” in the method signature inside healtPotion.h:



"virtual void useItem() override;"


Also, have you tried casting to healtPotion and then calling the method? Like this:



healthPotion hp = Cast<healtPotion>(item[0]);

if(healthPotion)
     healtPotion->useItem();
​​​​​​​​​​​​​​

Well it only works if I cast it but I lose all the functionality of polymorphism. I had in mind to use the base class pointer to iterate to a big array of pointers and access their functions no matter what types they are (inherited by main class). If I need to cast I have to do everything manually.

Stop using vanilla c++ in gameplay code for UObjects.
For what you want to do, to store them use



TArray<TSubclassOf<AmyItems>> ItemArray;


Btw, using AActor to represent inventory item instances is very bad idea. The Actor class cost a lot of memory in runtime; inventory systems should contain item IDs only.