I've been told that in case of exception thrown from a constructor, the object could remain patially constructed and have a global scope. This is why want to prevent a constructor from throwing. Moreover, Bjarne Stroustrup seemed to say it's not the best solution (but there is no better one).
In this case, the exception would be thrown form the factory method but not from the constructor
I assume cmdEvo intends to catch exceptions thrown by constructors. Either that or just suppress them, but I'll give some benefit of the doubt here.
There is a lot to dislike about C++'s exceptions, but leaving objects partially initialized if an exception is thrown is not one of them. Even in the case of non-local static variables, this does not happen. Instead, we get a call to std::terminate, and (usually) your program ends before main() even runs.
Moreover, what do you hope to accomplish by using factory functions here? Because if a constructor throws an exception, that's the constructor's way of signalling that an object cannot be constructed. Yet, your factory function still has to return something. What will it return? There are a few valid options here, but I'm curious if you've thought about them.
In case of wrong agument, the factory would throw an exception (because I thought il was not a good practice to throw from a constructor).
However, the factory should have returned a null shared_ptr I think. What is your opinion ?
If the problem is just an incorrect parameter I usually simply add a bool ok member to the class which the caller has to check afterwards. E.g.
1 2 3
Foo foo(bar);
if (!foo)
//foo is invalid
This is to avoid throwing an exception. Not because it's unsafe, but because it's expensive. I only let the constructor throw if performing this check in the caller is not feasible or if the error really is unrecoverable and more drastic measures are needed.
the factory should have returned a null shared_ptr I think. What is your opinion ?
my opinion is that constructors throw on errors (as in the quoted guidelines). Also factory functions should not return shared_ptr. A factory returning an optional/either/outcome/whatever<T> (non-throwing) or a unique_ptr<T> (may throw bad_alloc) or a container like vector<T> that may be empty (may throw bad_alloc) is sometimes the right thing to do, if you didn't really need that object(s).