Confused by the following coding style

No. Did you miss my post?

Definitely not. If the FObjectFinder isn’t static, then it is invoked for every call to the constructor. It’s “one time” for instances (though in truth, the constructor is not guaranteed to be called) but you’re still senselessly doing the same object find/load for each call to the constructor. If it is static, then it is invoked once (for the CDO) and the result persists for all instances.


void myobject::a()
{
	static ConstructorHelpers::FObjectFinder<UBlueprint> myJoyBP(TEXT("Blueprint'/Game/Characters/JoyGemBP.JoyGemBP'"));
	myJoyBP->DoThis();
}

The namespace “ConstructorHelpers” kind of gives it away, but this won’t work. FObjectFinders are meant to be used only in constructors. Try to use it outside of a constructor and it will raise an exception. You could instead use StaticFindObject/StaticLoadObject as FObjectFinder does internally, but then you would lose the entire point of this approach.

In UE4, constructors are meant to initialize the default object, not to construct instances. Instances are constructed from the default object, so in a way, the constructor will still indirectly construct instances. But in the case of loaded objects, the constructor can be skipped outright. In which case the only construction you get is from serializing the CDO as well as object values.

Strictly speaking, it is not necessary that this initialization be done for the default object (in the constructor). But a lot of things in the engine depend on the default object’s properties. This is why the object finder is static, but the member variable it assigns the object to is not. This way, whatever object or class was found using the object finder will be included in the CDO, allowing serialization and proper reference gathering for cooking.