Class Method Inheritance Issues

I’ve had a ton of trouble with class inheritance in UE4, so I made 2 simple classes to try and solve the issue, but it’s still not working. The derived class just uses the method of the base class:

Base class:


UCLASS()
class TEST_API ALivingThing : public ACharacter {
GENERATED_BODY()

public:
virtual void setupLivingThing();

protected:
UPROPERTY(EditAnywhere)
uint32 health;
UPROPERTY(EditAnywhere)
uint32 maxHealth;
UPROPERTY(EditAnywhere)
bool alive;

public:
// Sets default values for this character's properties
ALivingThing();

// Called every frame
virtual void Tick(float DeltaTime) override;

protected:
// Called when the game starts or when spawned
virtual void BeginPlay() override;
};


Derived class:


UCLASS()
class TEST_API AEnemy : public ALivingThing {
GENERATED_BODY()

public:
virtual void setupLivingThing() override;
};

There’s no reason it wouldn’t work, this is just native C++.

Are you sure the class you’re debugging is of type ‘AEnemy’ - and did you do something different in setupLivingThing()?

Hi Phoenex,

Could you post the code from the your DerivedClass.cpp.

without seeing it i would just ask if you are calling Super::setupLivingThing() in the derived class function as that would make the parent class’ code run.

Thanks for the replies! I’m somewhat new to C++, so I didn’t realize that I messed up because of this:

In the constructor for ALivingThing, I called setupLivingThing(). This calls ALivingThing::setupLivingThing(), regardless if it’s the base class or derived class. In order to call my unique method Enemy::setupLivingThing(), I had to also call setupLivingThing() in the constructor for AEnemy. Because I didn’t have a unique constructor for AEnemy, it called the base methods.

Old derived class:



#include "LivingThing.h"

void ALivingThing::setupLivingThing() {
maxHealth = 100;
health = maxHealth;
alive = true;
}

void ALivingThing::BeginPlay() {
Super::BeginPlay();
}

void ALivingThing::Tick(float DeltaTime) {
Super::Tick(DeltaTime);
}


New working derived class with a constructor that calls overridden methods:



#include "LivingThing.h"

ALivingThing::ALivingThing() {
PrimaryActorTick.bCanEverTick = false;

setupLivingThing();
}

void ALivingThing::setupLivingThing() {
maxHealth = 100;
health = maxHealth;
alive = true;
}

void ALivingThing::BeginPlay() {
Super::BeginPlay();
}

void ALivingThing::Tick(float DeltaTime) {
Super::Tick(DeltaTime);
}


So this is a classic gotcha with C++. This is because during the constructor for ALivingThing that’s all it is, the constructor for AEnemy hasn’t happened yet so it’s not actually an AEnemy yet. It’s generally considered bad practice to call virtual functions as part of the constructor or destructor in C++, because naïve implementations like this that seem like they should work but don’t.

Two better suggestions would be:

  1. Don’t have the setupLivingThing method at all. Your old version where you set the members during the ALivingThing constructor would work just fine to set it’s members. You would then use the AEnemy constructor to set AEnemy members (or modify ALivingThing members)
  2. Move the call to setupLivingThing to a place where the virtual call will work as expected, which is almost anywhere except the constructor or destructor. If you only have one system creating these actors, that system could call the setup function directly after spawning the actor. Or ALivingThing could override AActor::BeginPlay and call setupLivingThing.