How do I prevent instances of UObjects from being created automatically?

Hi all,

I’ve been writing a C++ library that interfaces with a C-like API for some physical hardware. We first implemented it as a Plugin, and then upon discovering this issue, switched to a Game Module, however the issue persists.

The issue is that something is creating an instance of the class (which we derive from UObject and FTickableGameObject), so when BeginDestroy is being called, it gets called twice - once on the one we created via our Game Instance, and once on this ghost copy which is being created by… something. - This is an issue because if you try to disconnect from the hardware when it’s already been disconnected, it’ll throw an error and leave us in a bad state.

Inside the BeginDestroy function we have the following snippet of code:
UE_LOG(LogTemp, Log, TEXT(“Destroying CompuTrainer %s on Port %d”), *GetOuter()->GetFullName(), Port);

If we make our own instance via the Game Instance (and Construct Object), it prints twice. The outer of one is the Game Instance, and the outer of other is:

[2016.01.30-05.23.08:757][227]LogTemp: Destroying CompuTrainer Package None on Port 0

So the issue here is that: Something is creating an instance of our UCompuTrainer (UObject derived) class automatically. We do not want it to be created automatically.

I went as far as moving the module into a brand new UE4 project, modifying the .uproject to add the Module, and running an empty scene. This prints out one entry into the log, indicating that the Game Module is automatically creating an instance.

The .uproject is as follows:

{
	"FileVersion": 3,
	"EngineAssociation": "4.10",
	"Category": "",
	"Description": "",
	"Modules": [
		{
			"Name": "CTTest",
			"Type": "Runtime",
			"LoadingPhase": "Default"
		},
		{
			"Name": "CompuTrainerModule",
			"Type": "Runtime",
			"LoadingPhase": "Default"
		}
	]
}

The Build.cs for the Module is linked right here.
The actual IModuleInterface implementation is effectively empty (Startup/Shutdown Module simply UE Log something).

The source for the UObject derived class is linked here

What on earth is creating this instance? It’s really driving me up the wall here!

1 Like

This is what’s known as the ‘class default object’ (CDO), and is central to how the UObject system works. Every UObject-derived class will have one created at startup.

You can test whether an object is the CDO by doing:

if(HasAnyFlags(RF_ClassDefaultObject))

Generally, you should avoid doing any setup in a UObject constructor other than simple property initialization and default subobject creation. Heavy setup, and anything that relies on other objects, should be deferred to some later override, or a custom initialization function. In this function, you may want to do a test and skip the logic if it is the CDO. That way, when the CDO gets destroyed, it won’t have setup any resources so a simple check of a member variable should tell you there is nothing to release/disconnect from.

1 Like

Does this mean that there is no way to override this behavior?

Is there a way to get a reference to this instance at runtime, other than using static singleton/static functions for everything? I suppose finding objects of class would likely return this instance.