
On 1/02/2018 19:09, Emil Dotchevski wrote:
The factory method technique also allows somewhat restoring a stronger invariant -- only the constructor and destructor need to cope with empty or otherwise uninitialised instances; other methods can be reasonably assured that no such instances escaped the factory method.
This is true only if you use exceptions to report errors from the factory. Otherwise it is most definitely NOT reasonable for member functions to assume that the object has been initialized, because nothing guarantees that an error reported by the factory wasn't ignored.
The factory itself provides that guarantee. One such pseudo-code implementation might be: static std::unique_ptr<A> A::create(args...) noexcept { // the constructor is itself noexcept and cannot fail std::unique_ptr<A> a(new (std::nothrow) A(arg1)); if (!a) return nullptr; if (!a->private_init_stuff(arg2, arg3, ...)) return nullptr; return a; } This can't return *why* it failed to create an A, but it cannot return an invalid A, assuming that private_init_stuff always returns false if it failed to satisfactorily init the object. Thus any public members of A (and basically anything other than the constructor, destructor and what is directly called from here or there) can always assume it has a fully valid instance, whatever that means. If you don't like the heap usage, the same concept applies if it returns an optional instead of a pointer (assuming it has a no-fail move). With Boost.Outcome, it can be implemented exactly as above (including not letting an invalid instance escape), but *also* indicate a failure reason to the caller, through a simple change to the return type. Are exceptions cleaner and shorter? Of course. But this still works, and some people will prefer it due to perceived latency issues with exceptions, or just personal issues with exceptions in general, or with "hidden code paths" expressly due to the code being shorter. (Whether those issues are real or not, I cannot say.)