If we were to mention all possibilities:
By allowing zombi objects, user shouldn't do anything with them unless he has called a function like is_good and found that it returned true:
Class MyClass
{
public:
MyClass(int no);
bool is_good() const { return good; }
private:
bool good;
};
MyClass::MyClass(int no): good(no >= 0)
{
}
int main()
{
MyClass m(100);
if (m.is_good()) {
//Go ahead and use it
}
}
Technically it would be possible to add runtime checks that the instance is not used unless is_good() was called and returned true.
This is the approach iostreams have taken.
Some people would also mention out parameters for the constructor (gets weirder and weirder):
Class MyClass
{
public:
MyClass(int no, bool& success);
};
MyClass::MyClass(int no, bool& success)
{
success = no >= 0;
}
int main()
{
bool result;
MyClass m(10, result);
if (result) {
//go ahead and use m
}
}
Personally I find this a bit too awkward.
Neither of those prevent creation of an instance. Only throwing an exception can really abort object construction, so it is never completed.