I would not go with an invalid object approach at all, because I consider this a bad design. After construction, the object must be in the state in which the invariants are set (this is the only goal that the constructor must fulfill). Consider the strange_vector class that implements something like std::vector , but after calling strange_vector<int>(10, 0) object will be in an unusable state because the selection failed.
Instead, I would declare private constructors and use the factory method, which returns an optional parameter:
class file { public: ~file() {fclose(m_file);} static std::optional<file> open(std::string const& filename) { auto f = fopen(filename.c_str(), "r"); if (f) { return std::make_optional<file>(f); } else { return std::nullopt; } } private: file(FILE* file); FILE* m_file; };
One of the biggest advantages of handling exceptions is (in addition to eliminating access errors and the usual code path) that you cannot ignore them by accident. If you want this, you can create your own class, similar to optional , which, if it is not initialized with a valid object, logs an error message and terminates your program (or any other reasonable error handling). I think there is talk from A. Alexandrescu about systematic error handling , where it implements the Expected<T> class, which contains either a value of type T or an exception. You can use this base, and instead of an exception add your error handling there.
std::optional is not yet part of the standard, but you can easily implement implementations as part of the latest compilers, in boost or in other libraries.
source share