C++ constructors construct a class. But in current C++ bindings, classes are actually wrappers around an existing Godot object. It is not true inheritance. It cannot be, because Godot exposes a C API, and C does not know what a class is.
So every class has to contain an additional field, which points to the Godot object it extends. This pointer needs to be initialized.
Problem: from what I recall, in a constructor without argument, there is no way to have this field initialized “automagically”. This means you can’t call Godot functions from it, at all. It would crash.
A solution would be to require every constructor to accept that pointer as argument, and also require them to call their parent constructor with that pointer. It’s a bit tedious though. Also, parameterless constructors would not be allowed, for the same reason.
But there is another problem: wrappers for Godot classes or your own sometimes need to get created, but not necessarily by your code, and not for the same reason. If a script passes you a Sprite, the Sprite already exists. But the object representing that Sprite in your library isn’t, and gets created on the fly behinds the scenes. That means if you were to use
new Sprite(), it won’t actually create the sprite. It will only create a “Sprite wrapper”. If it was also creating the underlying Godot object, then the mechanism I described earlier would fail, as passing an existing sprite for the first time into one of your functions would end up creating a new one instead.
So… it was decided that creating instances was done with
Class::_new() instead of
new, and that
_init() be created in addition to the C++ constructor to allow you to call functions of the extended object (mimicking GDScript).
Note, you can actually write code in the constructor. But calling Godot functions from there will crash.
_init could also be made optional, in the cases you don’t need it. The library would have to somehow find a way to make sure it fallbacks on a no-op, instead of calling the ill-formed
Object::_init() at the moment. It might be a bit error prone though.
About overriding: I didn’t experiment much with this on the C++ bindings, mostly because I don’t code this way much, but the same issue might be at stake: classes are C++ wrappers, they are not the true ones. So virtuality doesn’t cross boundaries.
I’m not sure which override you want to achieve, but if you mean in the C++ sense, it needs the overriden function to have the
virtual keyword if you want polymorphism to work. But again, that essentially won’t work this way with Godot object functions.