C++ doesn't zero-initialize instances before calling the constructor. Thus you can't tell which fields need to be cleaned up in a destructor in case of a partial construction [1]. So destructors aren't called for partial construction, and you need to handle the exception cleanup in the constructor. But you can't do that for member initialization lists, so there's this thing.
RAII and wrappers is one reasonable way out of the insanity, but the costs are arguably higher than zero initialization - certainly in ugliness of wrapper classes, if not in absolute runtime.
Forbidding exceptions in constructors is another reasonable way out, but that kind of sucks - constructors have no other way of communicating error, so you need to add isValid flags to your classes, and to be belt and braces secure, you need to check this flag for every operation.
The correct answer is zero initialization, possibly with some kind of pragma to prevent zero init for critical performance classes. The thing with zero init is that data flow analysis can mitigate the costs - the compiler would be able to eliminate the earlier zero assignment much of the time.
Overall it's more of the same from C++: unsafe, broken by default, bodged up with hacks to make it slightly more stable, and usually works mostly OK in practice owing to limiting C++ to a reasonable subset.
[1] I know that technically 0 can be a valid physical address, but even for (embedded) systems that do allocate there, it's worthwhile reserving it.