I have been doing some testing and have found that most of what has in his post is true with some differences.
CDO is created when engine is initialized when it generates UClass objects for each class,
This is true. An instance for each UClass is created during engine initialization and is assigned to be the CDO for that UClass.
then it naturally executes constructor setting default variables and it will never call constructor again
This seems to be false in my testing. The constructor of a given UClass object is called every time a UObject is created. However in these new instances the variables of the object will be overwritten by the variables from the CDO or from a previously serialized version of the object (e.g. an AActor in a level).
I created a simple test Actor (which of course ultimately derives from UObject) called “ARandomPropertyActor” and placed 11 of them into a new level. The constructor of this actor sets MySpecialProperty to a random integer and prints it to the log. On BeginPlay for the actor I also print out each instances MySpecialProperty as well as getting the CDO for the UClass and printing it out.
The funny thing I find is that when I place new instances of ARandomPropertyActor into the level, their constructor is called and their MySpecialNumber is set to the random value. (the CDO is not used as a template).
I’m still trying to get the bigger picture here but thought I would post what I’ve know so far as there is very little documentation (apart from the source code) on the UObject lifecycle at runtime and in the editor.