Cannot implement OnOverlapBegin/End in base class

Hey Guys,

I have a problem with the OnOverlapBegin/End Event. I have a base class which derives from AActor and it should have the OnOverlapBegin/End function for base implementation of the function. But I got here a lot of unresovled external errors in derived classes or classes which implements the class.
Now I tried to implement the OnOverlapBegin/End function in a derived class and it seems to work there. So now my question is. Why does it work in the derived class and not in the base class? I will give u example code:



//this doesn't work
Uclass(abstract)
class (ProjectName)_API baseClass : public AActor
{
GENERATED_BODY()

public:
UFUNCTION()
         void OnOverlapBegin(class UPrimitiveComponent* OverlappedComp, class AActor* OtherActor, class UPrimitiveComponent* OtherComp, int32 OtherBodyIndex, bool bFromSweep, const FHitResult& SweepResult) ;

UFUNCTION()
         void OnOverlapEnd(class UPrimitiveComponent* OverlappedComp, class AActor* OtherActor, class UPrimitiveComponent* OtherComp, int32 OtherBodyIndex);
};

//this work (for sure here isn't the OnOverlapBegin/End function implemented in baseClass
Uclass(abstract)
class (ProjectName)_API derivedClass :public baseClass
{
GENERATED_BODY()

public:
UFUNCTION()
         void OnOverlapBegin(class UPrimitiveComponent* OverlappedComp, class AActor* OtherActor, class UPrimitiveComponent* OtherComp, int32 OtherBodyIndex, bool bFromSweep, const FHitResult& SweepResult) ;

UFUNCTION()
         void OnOverlapEnd(class UPrimitiveComponent* OverlappedComp, class AActor* OtherActor, class UPrimitiveComponent* OtherComp, int32 OtherBodyIndex);

};

does anybody know why this work? Because I don’t wanna have an abstraction level just for collision detection. The derived class has also some other dervied class from it so I don’t think it’s any kind of abstraction level here.

You have two issues here. The first is that you will get Linker Errors if you don’t create the implementation of a UFUNCTION() in a class - so make sure you have a corresponding .cpp file and implement the functions there.

The second issue is that this isn’t how C++ works. You don’t redefine the function in the derived class, you override it.The declaration in the base class needs to be ‘virtual’, so that a child class can override it, like so:



class BaseClass
{
    virtual void SomeOverrideableFunction();
};

class DerivedClass : public BaseClass
{
    virtual void SomeOverrideableFunction() override;
};


Additionally, the ‘Abstract’ key word for UCLASS doesn’t do what you would expect since UCLASS() objects are always created somewhere (e.g, as a class-default object - an Unreal term). It just means the class can’t be instantiated directly in the editor. If you want to create a true ‘abstract’ class then you need to use an interface with pure virtual functions like so:



class SomeInterface
{
    // Child classes will not compile unless they override this function
    virtual void SomeVirtualFunction() = 0;
};

class ASomeClass : public SomeInterface
{
    virtual void SomeVirtualFunction() override {}
};


Yeah I just didn’t write the implementation because it doesn’t matter here. I think u didn’t read the comments I made in code. The first is the example which doesn’t work and the second is which works.In the second there is no declaration like the first the OnOverlapBegin/End doesn’t exit in base class in the second example.
And yes the abstract keyword make everything I want here. I just don’t wanna have the base classes to get initialized, don’t need an interface here.

EDIT: And the OnOverlapBegin/End Functions shouldn’t be pure virtual function because I want an implementation in the base class for all derived classes.

I don’t understand - I’m going by the code you put in the snippet, which as it’s written there won’t compile for the reasons I listed above. If that isn’t the code you’re trying to compile then we can’t really help.

Unresolved externals usually means you haven’t implemented something that must be implemented, such as a virtual function or a UFUNCTION, or you’re trying to reference a non-exported object.

Ok I will clean it a bit up.
Here is the code which doesn’t work:


// baseClass.h
UClass(abstract)
class (ProjectName)_API baseClass : public AActor
{
GENERATED_BODY()

UFUNCTION()
void OnOverlapBegin(class UPrimitiveComponent* OverlappedComp, class AActor* OtherActor, class UPrimitiveComponent* OtherComp, int32 OtherBodyIndex, bool bFromSweep, const FHitResult& SweepResult);

UFUNCTION()



void OnOverlapEnd(class UPrimitiveComponent* OverlappedComp, class AActor* OtherActor, class UPrimitiveComponent* OtherComp, int32 OtherBodyIndex);
};

// baseClass.cpp
void baseClass::baseClass::OnOverlapBegin(class UPrimitiveComponent* OverlappedComp, class AActor* OtherActor, class UPrimitiveComponent* OtherComp, int32 OtherBodyIndex, bool bFromSweep, const FHitResult& SweepResult)
{}
void baseClass::baseClass::OnOverlapEnd(class UPrimitiveComponent* OverlappedComp, class AActor* OtherActor, class UPrimitiveComponent* OtherComp, int32 OtherBodyIndex)
{}

And here is the code which works


// baseClass.h
UClass(abstract)
class (ProjectName)_API baseClass : public AActor
{
GENERATED_BODY()



};

// derivedClass.h
UClass(abstract)
class (ProjectName)_API derivedClass : public baseClass
{
GENERATED_BODY()

UFUNCTION()
void OnOverlapBegin(class UPrimitiveComponent* OverlappedComp, class AActor* OtherActor, class UPrimitiveComponent* OtherComp, int32 OtherBodyIndex, bool bFromSweep, const FHitResult& SweepResult);

UFUNCTION()
void OnOverlapEnd(class UPrimitiveComponent* OverlappedComp, class AActor* OtherActor, class UPrimitiveComponent* OtherComp, int32 OtherBodyIndex);
};

// derivedClass.cpp
void derivedClass::derivedClass::OnOverlapBegin(class UPrimitiveComponent* OverlappedComp, class AActor* OtherActor, class UPrimitiveComponent* OtherComp, int32 OtherBodyIndex, bool bFromSweep, const FHitResult& SweepResult)
{}
void derivedClass::derivedClass::OnOverlapEnd(class UPrimitiveComponent* OverlappedComp, class AActor* OtherActor, class UPrimitiveComponent* OtherComp, int32 OtherBodyIndex)
{}


So maybe u see now. That in the example which works the class just derives from the empty baseClass but everything else is the same in the baseClass. And I know what the unresolved external errors mean, but I don’t know what I’m doing wrong here because in the second example the code works.

EDIT: I don’t know why this site generates random


 

makros xD Hope you can read though.