Interface in C++; can you pass variables between objects of different classes?

Hi All

I’ve seen this question answered for BP’s but not C++. Is it possible to use a C++ interface to pass variables between objects of different classes? If so, what would that look like in code?

Thanks!

EDIT: I’ve made an abstract base class with static member functions and static data members (so far just bools). This seems like its almost the same- infact an abstract class and interfaces are almost interchangeable as they are spoken about on Stack Overflow (if that’s a good authority). Does anyone have anything to add to this, or an answer to the original question?

Durrrr. I’m guessing that you can have private data members in the interface that are also static? That way all the classes that share the interface can do what they need to do, to that data. So one classes implementation of a virtual function may be writing to that data, another may be using the data etc. Exactly what I wanted, I just had trouble making that step from Rama’s tutorial…

So something like;

h;

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

class IMyInterface
{
	GENERATED_IINTERFACE_BODY()

		virtual FString ToString();

private:

	static bool bTestForSomeShit;
};

cpp;

bool IMyInterface::bTestForSomeShit = true;

Please comment if this is completely wrong!

EDIT: Just found this-

Also, just found this, for anyone who’s having the same difficulty as I was thinking about it- an abstract class or interface in C++ is basically just another class, it isn’t “virtual”;

That doesnt seem to work. So far the abstract base class with the static functions and data members is working, just wondering why I cant get Rama’s solution linked to in the answer to work…

I succeeded in getting the static bool and also a static struct to compile in the interface, but that’s, presumably, a complete waste of time. A virtual function couldn’t be static.

Rama’s solution doesn’t seem to work unless I’ve messed it up.

So I’m thinking maybe the only way to do this properly is with an abstract class?

It seems like static is the way to go. I’ve read answers on here which suggest that the static keyword is for variables etc which don’t change much. That’s a misconception. A static data member or function is in the class scope, so the value is the same for each object of the class. It will retain it’s value between calls to a function if used in a function, or in every object of the class.

I’ve done a bunch of different tests and it seems as if its also possible to make a static delegate signature, and fire a delegate in the interface from a virtual function in one class, that’s bound to a function in another class. In the header of the interface;

DECLARE_DELEGATE_OneParam( FDelegateSignature, AActor* )

UINTERFACE(MinimalAPI)
class UTestInterface : public UInterface
{
	GENERATED_UINTERFACE_BODY()
	
};

class MY_API ITestInterface
{
	GENERATED_IINTERFACE_BODY()


	static bool GetTestBool();

	static void SetTestBool(bool NewValue);

	static void AddToTestArray(AActor* Other);

	static void RemoveFromTestArray(AActor* Other);

	static int32 GetArraySize();

	virtual void FireDelegate(AActor* TestActor) = 0;

	static FDelegateSignature MyTestDelegate;

private:
	

	static TArray<AActor*> TestArray;

	static bool bTestBool;


};

In the cpp:

UTestInterface::UTestInterface(const class FObjectInitializer& ObjectInitializer)
	: Super(ObjectInitializer)
{

}


TArray<AActor*> ITestInterface::TestArray = {};

FDelegateSignature ITestInterface::MyTestDelegate = {};

bool ItestInterface::bTestBool = true;



bool ITestInterface::GetTestBool()
{

	return bTestBool;
}

void ITestInterface::SetTestBool(bool NewValue)
{

	bTestBool = NewValue;
}

void ITestInterface::AddToTestArray(AActor* Other)
{
	TestArray.Add(Other);
}

void ITestInterface::RemoveFromTestArray(AActor* Other)
{
	TestArray.Remove(Other);
}

int32 ITestInterface::GetTestArraySize()
{
	return TestArray.Num();
}

It’s important to remember to override the pure virtual function in every class that uses the interface, otherwise it won’t compile. Then in the constructor of the UObject where the delegate will fire I’ve got;

MyTestDelegate.BindUObject(this, &UMyUObjectClass::SomeFunction);

And in the class that is sending, in the function that overrides the pure virtual FireDelegate interface function I’ve got;

MyTestDelegate.Execute(TestActor);

This all works fine. I can use the static delegate to send messages directly from one class to another, or I can store info in the static data members of the interface and access those from objects that share the interface when needed.

I’ve made a few assumptions here so, anyone who’s expert at coding, please comment if I’ve done something wrong or unsound!

EDIT: I think maybe the reason why static data members are (seemingly, reading between the lines) discouraged in UE4 is because they are initialized when the program starts. So it looks like in the editor, they retain their value even between begin plays. Which means that, if you do this, you probably need to reset the static data members when the level unloads, or at some point that guarantees you begin a fresh play session with the static data members as you expect them to be.

I realize that this is an old post and you have probably found the correct path by now, but just in case anyone else comes to this post looking for answers.

It is totally possible to use interfaces in UE4 to communicate between different object types … I even use interfaces for interaction with various blueprint types so that they can be used by any class that implements that interface very successfully.

Here is a small sample from my TPP Controller interface

class MYGAME_API UTPPControllerInput : public UInterface
{
    GENERATED_UINTERFACE_BODY()
};

class MYGAME_API ITPPControllerInput
{
    GENERATED_IINTERFACE_BODY()

public:
    UFUNCTION(BlueprintNativeEvent, BlueprintCallable, Category = "Controller Input")
    void Invoke_Crouch();
}

As you can see no static is required

You can use this in C++ like this (can be a member variable or local variable)

TScriptInterface<ITPPControllerInput> tppInterface;
if (myImplementation->GetClass()->ImplementsInterface(UTPPControllerInput::StaticClass()))
{
    tppInterface.SetInterface(dynamic_cast<ITPPControllerInput*>(myImplementation));
    tppInterface.SetObject(myImplementation);
}
tppInterface->Execute_Invoke_Crouch(myImplementation);

This interface can also be called directly from blueprints (e.g. character blueprint or animation blueprint) and is useful for having single animation blueprint usable by any class that implements this interface.