PURE_VIRTUAL interface

I read that true C++ pure virtual functions are not supported in Unreal but that we can use the PURE_VIRTUAL macro instead. The interface documentation says that pure virtual functions are supported so I tried creating an interface and using the PURE_VIRTUAL macro:

	// Add interface functions to this class. This is the class that will be inherited to implement this interface.
public:
	virtual void Test() PURE_VIRTUAL(ITestInterface::Test, );

Then I created a new Actor and made it also inherit from ITestInterface:

ATestActor : public AActor, public ITestInterface

I didn’t provide and implementation for Test() anywhere but it still compiles without giving me any kind of error or warning that I can see.

Where did I go wrong?

From what I can tell, PURE_VIRTUAL is a way to detect when an interface function has not been overridden. It creates a stub function that will generate a warning at runtime (not compile time). It’s more of a TODO marker than a modifier of a function declaration. Try running it.

This is it:

#if CHECK_PUREVIRTUALS
#define PURE_VIRTUAL(func,extra) =0;
#else
#define PURE_VIRTUAL(func,extra) { LowLevelFatalError(TEXT("Pure virtual not implemented (%s)"), TEXT(#func)); extra }
#endif

If CHECK_PUREVIRTUALS is 0 then you should get the message. If it’s defined then you’d get the compile-time error. Note that with it enabled, you can only compile. If you run it, this code gets executed:

#if CHECK_PUREVIRTUALS
	FMessageDialog::Open( EAppMsgType::Ok, *NSLOCTEXT("Engine", "Error_PureVirtualsEnabled", "The game cannot run with CHECK_PUREVIRTUALS enabled.  Please disable CHECK_PUREVIRTUALS and rebuild the executable.").ToString() );
	FPlatformMisc::RequestExit(false);
#endif

It’s disabled by default so if you don’t see the log message then something else isn’t right. And it shouldn’t crash. That may be a clue as to what is wrong. You could show the log of the crash and you could show the full interface and usage.

I tried running it and even calling it in BeginPlay() but I don’t see anything in the Output Log. The “Pure virtual not implemented” would show up in the Output Log at runtime?

Whoops, calling it was actually a crash once I made a blueprint from the actor and dragged it into the level. But I’m still checking for the warning message so I can see what the use of the macro is.

I can change to BlueprintType and build but when I try to use the interface-specific macros instead of GENERATED_BODY() I get linker error somehow involving the UMyInterface constructor:

1>MyInterface.gen.cpp.obj : error LNK2019: unresolved external symbol "public: __cdecl UMyInterface::UMyInterface(class FObjectInitializer const &)" (??0UMyInterface@@QEAA@AEBVFObjectInitializer@@@Z) referenced in function "void __cdecl InternalConstructor<class UMyInterface>(class FObjectInitializer const &)" (??$InternalConstructor@VUMyInterface@@@@YAXAEBVFObjectInitializer@@@Z)
1>D:\Unreal Projects\TestInterface\Binaries\Win64\UE4Editor-TestInterface.dll : fatal error LNK1120: 1 unresolved externals

I think that I will provide a default implementation for now because I’m not sure a simple log message is worth a lot of time and trouble.

Please don’t post comment replies in answer posts. Answers are for answers.

MinimalAPI doesn’t look like it’s going to work well with interfaces. And I’m using interface-specific GENERATED_XXX macros. Try this way:

UINTERFACE(BlueprintType)
class MY_API UMyInterface : public UInterface
{
	GENERATED_UINTERFACE_BODY()
};


class MY_API IMyInterface
{
	GENERATED_IINTERFACE_BODY()
...

Oh. Right. In the cpp file you need to implement the constructor. Like this:

UMyInterface::UMyInterface(const class FObjectInitializer& ObjectInitializer)
	: Super(ObjectInitializer)
{
}

Weird. It should do more than log a message cuz it’s calling LowLevelFatalError.

It’s just a utility macro – or, supposed to be hehe. You can write the message to the log yourself in the default implementation.

Builds now with BlueprintType and interface-specific macros but still not seeing anything. Oh well.

Ahh, I think I see how it works now. That crash that I mentioned before was the LowLevelFatalError. You have to call Test() and then it will crash the editor/game (if you launched it outside of Visual Studio from the Epic launcher) and the call stack will show:

LowLevelFatalError [File:d:\unreal projects\testinterface\source\testinterface\MyInterface.h] [Line: 28]
Pure virtual not implemented (IMyInterface::Test)

But if you launch from Visual Studio (or attach to process I assume) then it will throw and exception and break.

Unless I’m debugging something I usually launch the project from the Epic launcher. So I will definitely notice if I forget to provide an implementation! But I think I would prefer to find out at compile time. :slight_smile:

Aha! Mystery solved.

Unfortunately, the way UE4 uses its own pre-pre-processing and all their macro stuff, it’s going to be hard to get that info at compile time. You can try using the C++ pure virtual format (virtual void foo() = 0;). That’s what CHECK_PUREVIRTUALS does. But it would just be something that lets you check for anything that wasn’t implemented. You’d have to change it back to be able to build anything for real. It’d be faster to just check it at runtime.

Try to declare your pure virtual function like this:

virtual void Test() PURE_VIRTUAL(ITestInterface::Test, ;);

Please note that extra ; if you are returning void. If you are returning other value type, just provide default value or any value really.
You need to pay attention to implement that function in derived class otherwise you will get message like this: “Pure virtual not implemented”. Typical usage for this macro is if you want to make pure abstract base class.