Likewise for "super", because Java allows subclasses to modify parent fields, which need to be initialized to fulfill the same contract.
Swift, which has the same contract, splits the "initialization" phase from the "construction" phase, so you can indeed modify internal state prior to calling "this()" or "super()".
This contract doesn't hold anyway, because you can call object's methods from the constructor before the object initialization finishes, and those methods can even call the overriding code in the derived classes. So even though `super` is guaranteed to be initialized fully, `this` is not.
It is complicated and I'm sure it has caused some bugs, but it has also solved some bugs.
While the idea is reasonable on its face, it's convoluted enough in practice that it used to be a common source of interview gotchas, so I'm not sure that it fixes more problems than it creates in practice.
From syntax perspective, the parent and member constructors (in C++) are in a special list outside function body, it doesn't tease you with it looking like a regular statement inside the constructor body.
C++ not only has constructors, but default constructors and destructors. If an exception gets thrown, the compiler needs to ensure that destructors will get called only for the parent classes and members that were initialized. It does so by having very specific order in which the parent and member constructors and destructors get executed. The use RAII mechanism also means that C++ developers are more likely to make classes where construction/destruction has sideffects which need to happen in specific order.
Unlike Java where due to all the classes are reference types semantics uninitialized members can be left pointing to null, in c++ any nontrivial member will have the constructor called no matter what. If you don't do it explicitly the default constructor will be called. Implicitly or explicitly in both cases the member constructors will be called in the definition order !BEFORE! the constructor body, but after the parent constructor call.
As if things weren't complicated enough, C++ not only supports multiple inheritance it supports the diamond case in both ways: with the shared base class duplicated, and in case of virtual inheritance with shared base class not being duplicated. With all that complexity compiler still needs to ensure that right subset of destructors get executed in case of exception during construction.
Some of these problems Java solves with the help of garbage collector. If you get some members laying around after failed construction in Java, sooner or later it will be cleaned up by GC, and since Java doesn't have destructors it isn't critical when exactly it happens.
It was a painful learning process from there to where we are now, where we consider any internal state that isn't passed to the constructor in an already immutable shape a considerable smell that you'd better have very good reasons for and we prefer a clear distinction of preparation and operation phases separated by that one constructor which sets (and in most post-OOP languages also declares) the values of the object's constituents.
(PS why isn't "post-OOP" a far more established term? It feels considerably more useful to me than the usual mind gymnastics about "functional but not quite" that provoke all those (im)purity squabbles that help noone)
Being able to put an object into a specific well defined state at the time of instantiation is really good.
Figuring out what to pass a constructor and the actual allocation are different tasks. The anti pattern is conflating them. It's fine to use constructors.
The factories will call the constructor, they kind of look similar
The constructors could still be public, so if you don't have the need to do anything fancy, you might still just call one of the simple constructors directly. However, you often see that API designers restrict this approach in favor to a single point of entry into creating objects of that class. That is, you then have to create objects via a factory, even if you could as easily pass already existing values to a simple constructor. But that's a different story.