
On 02/01/18 10:01, Jonathan Müller via Boost wrote:
On Feb 1, 2018 7:56 AM, "Emil Dotchevski via Boost"
wrote: On Wed, Jan 31, 2018 at 10:30 PM, Gavin Lambert via Boost < boost@lists.boost.org> wrote:
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 does not protect the user at all:
std::unique_ptr<A> a=A::create(); a->foo(); //undefined behavior
Compare to:
static std::unique_ptr<A> A::create(args...) { std::unique_ptr<A> a(new A(arg1)); //new throws on error, A::A() throws on error return a; }
And then:
std::unique_ptr<A> a=A::create(); a->foo(); //Okay, a is guaranteed to be valid.
Yeah but you can write stupid code with anything:
``` std::unique_ptr<A> a; try { a =A::create(); } catch (...) {} a->foo(); // ups ```
The important difference between using exceptions and error codes (or Boost.Outcome, I presume) is that in case of exceptions the user has to make an effort to write broken code and the correct code most of the time comes naturally, while with manual error checking it is the other way around. This is the reason why manual error checking is more prone to mistakes in error handling. PS: All that, of course, is given that RAII is ubiquitous. If it's not then error handling is difficult regardless of the tool you use.