Clarification on implementing abstract ActorComponents

I’m pretty sure this is a syntax issue, not a structural issue, but I’ve implemented an abstract base class, and I’m struggling to figure out how to override virtual methods with actual content in classes that inherit from it.

The base, abstract class, extended from UActorComponent and created with the abstract keyword in the UCLASS macro, and a single virtual function Attack(), meant to be overridden.


UCLASS( ClassGroup=(Custom), abstract )
class CODEPROJECT_API UIMorpheme : public UActorComponent
{
	GENERATED_BODY()

public:	
	// Sets default values for this component's properties
	UIMorpheme();

	virtual void Attack() { check(0 && "You must override this"); };


	// virtual TArray<AGround*> MyFunc() { check(0 && "You must override this"); return TArray<AGround *>(); } EXAMPLE OF HOW TO RETURN VALUE WITH ABSTRACT
	// Called when the game starts
	virtual void BeginPlay() override;
	
	// Called every frame
	virtual void TickComponent( float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction ) override;
};

This compiles fine, so I was under the impression that I declared and configured it correctly. The next step is to make a class that inherits from UIMorpheme, and attempt to override virtual void Attack() with functionality:

.h:


UCLASS()
class CODEPROJECT_API UIMorphemeVerb : public UIMorpheme
{
	GENERATED_BODY()
		void Attack();
	};

.cpp:


#include "CodeProject.h"
#include "IMorphemeVerb.h"


void Attack(){
	GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Red, TEXT("Attack() function triggered!"));
}

I thought this was formatted correctly as well, but it creates three errors that I’m having an awful lot of trouble deciphering:




Error IMorphemeVerb.cpp.obj : error LNK2001: unresolved external symbol "private: virtual void __cdecl UIMorphemeVerb::Attack(void)" (?Attack@UIMorphemeVerb@@EEAAXXZ)
Error MVAttack.cpp.obj : error LNK2001: unresolved external symbol "private: virtual void __cdecl UIMorphemeVerb::Attack(void)" (?Attack@UIMorphemeVerb@@EEAAXXZ)
Error CodeProject.generated.cpp.obj : error LNK2001: unresolved external symbol "private: virtual void __cdecl UIMorphemeVerb::Attack(void)" (?Attack@UIMorphemeVerb@@EEAAXXZ)

Assuming it’s kosher to make an actorcomponent virtual (which I’m assuming it is), I’m really hoping that my problem is sloppy syntax, but I can’t see where I would’ve futzed up.

Its


void UIMorpheme::Attack()

in the cpp file, you forgot the class part.

Oh hey, that’s an easy fix- it works now, thank you!

For running multiple layers of an inherited function I know the syntax is Super::myFunction() inside each layer , but how do I need to declare a function inside, say, UIMorphemeVerb, to run both it, and its child in MVAttack : UIMorphemeVerb? I tried making the declaration virtual void inside UIMorphemeVerb and void in MVAttack, but that started throwing errors.

You call the base class version in your methods by calling the full name.



class A
{
public:
  virtual void Method()
  {
  }
};

class B : public A
{
public:
  void Method() override
  {
    A::Method();
  } 
};


Go fetch a C++ tutorial, its just a bit complicated to lern. :slight_smile:

Coming from C# it’s especially frustrating, since I intellectually know what I want to do, but working out the syntax and learning UE4’s macros and idiosyncrasies can be challenging :slight_smile:

I think what I was missing was the override specifier in my terminal function, I got it all fixed up and works perfectly now, thank you!! :slight_smile:

I do notice that you have override in your definition, is it acceptable to only have it in the declaration? I got an error keeping it in the definition, but it runs perfectly if I do

.h:


void Method() override;

.cpp:


void Method(){
//Implementation
}

Yea its just for the definition, not for the implementation; if you split it apart.

I think the override keyword isnt even required at all, it just helps you to make sure you do override a virtual base method, if along the course of development (or think engine upgrades) things change and the base class method isnt virtual anymore the compiler will tell you theres an error now if you put override at the declaration.

You forgot the class part in the cpp sample again :wink:

I think I’m going to start keeping a spray bottle of water next to my desk and using negative conditioning every time I leave out the class :slight_smile: