I wrote a function that has to initialize a temporary object (derived from UObject) and may or may not be called from inside a constructor.
The problem: If called inside a constructor the function needs to utilize CreateDefaultSubobject<>(), if called outside a constructor it must use NewObject<>(). But how does the function know whether it is called inside or outside of a constructor?
NOTE: I would like to make this code somewhat smart. I know I could just be lazy and write two separate functions, use a bool parameter to tell my function which initialization method to use or just use the try-catch-routine.
But those solutions feel pretty messy or inconvenient, so I’d rather search for an alternative.
Thanks in advance!
There really no way, because when you compile the code all the function information is lost or else you write code that tracks it. you could try to check object iniation stage by checking object flags
You can get them from function GetFlags()
EDIT: Actully i remind myself about this ConstructoirHelpers will throws a error when being called outside constructor, so UE4 has some tracking if thread is in constructor:
void ConstructorHelpers::CheckIfIsInConstructor(const TCHAR* ObjectToFind)
auto& ThreadContext = FUObjectThreadContext::Get();
UE_CLOG(!ThreadContext.IsInConstructor, LogUObjectGlobals, Fatal, TEXT("FObjectFinders can't be used outside of constructors to find %s"), ObjectToFind);
Not sure if it is what you are looking for, but look into function pointers
This is highly interesting. I’m pretty new to UE4 though so there’s a lot of engine specific stuff (like ConstructionHelpers) I have no idea about. That means this research is probably going to take a while…
I’ll let you guys know, if I find something usefull!
This would be one way to do it, but I woould still have to write multiple functions. It is certainly more elegant than using a “IsCalledByConstructor” parameter inside my function but still not ideal…
Ok, you were totally right!
I found a more clear example in the SceneComponent.cpp file
FUObjectThreadContext& ThreadContext = FUObjectThreadContext::Get();
if (ThreadContext.IsInConstructor > 0)
This is going to be handy!
To add to Shadowriver’s answer, it’s essentially due to how C++ was intentionally designed (see stack overflow). It doesn’t allow calling virtual functions from a constructor as the language is trying to protect you from null references. Personally I don’t like this either, but it makes some sense. Also read the linked FAQ, especially the part regarding using the “Dynamic Binding During Initialization idiom”.
“It doesn’t allow calling virtual functions from a constructor”
Compiler only prevents you from calling pure virtual method from constructor immediately (but you still can simulate pure virtual call via additional method wich calls pure one)