Лучшее предложение, вероятно, то, что говорит Parashift. Но, пожалуйста, прочитайте мое предупреждение также ниже.
См. Часто задаваемые вопросы по parashift 17.2
[17.2] Как я могу обработать конструктор
что терпит неудачу?
Брось исключение.
Конструкторы не имеют возвращаемого типа,
так что невозможно использовать возврат
коды. Лучший способ подать сигнал
отказ конструктора, следовательно,
бросить исключение. Если у вас нет
возможность использования исключений,
«наименее плохой» обходной путь, чтобы поставить
объект в состояние "зомби"
установить бит внутреннего состояния, чтобы
объект действует вроде как он мертв
хотя технически это все еще
жив.
Идея "зомби" объекта имеет
много минусов. Вам нужно добавить
функция-член запроса ("инспектора") для
проверьте этот бит "зомби", чтобы пользователи
ваш класс может узнать, если их
объект действительно жив, или если это
зомби (то есть, объект "живых мертвецов"),
и почти в каждом месте, где вы
построить один из ваших объектов
(в том числе внутри более крупного объекта или
массив объектов) нужно проверить
этот флаг состояния через оператор if.
Вы также хотите добавить if к вашему
другие функции-члены: если объект
это зомби, делать не-операции или, возможно,
что-то более неприятное.
На практике "зомби" получает
довольно уродливые. Конечно, вы должны
предпочитаю исключения объектам зомби,
но если у вас нет возможности
используя исключения, объекты зомби могут
быть "наименее плохой" альтернативой.
Предостережение с использованием исключений в конструкторе:
Будьте очень осторожны, потому что, если в конструкторе выдается исключение, деструктор класса не вызывается. Таким образом, вы должны быть осторожны при уничтожении объектов, которые вы уже создали, прежде чем будет сгенерировано исключение. Те же самые предупреждения применимы к обработке исключений в целом, но, возможно, это немного менее очевидно при работе с конструктором.
class B
{
public:
B()
{
}
virtual ~B()
{
//called after D's constructor's exception is called
}
};
class D : public B
{
public:
D()
{
p = new char[1024];
throw std::exception("test");
}
~D()
{
delete[] p;
//never called, so p causes a memory leak
}
char *p;
};
int main(int argc, char **argv)
{
B *p;
try
{
p = new D();
}
catch(...)
{
}
return 0;
}
Защищенные / частные конструкторы с методом CreateInstance:
Другой способ - сделать ваш конструктор частным или защищенным и создать метод CreateInstance, который может возвращать ошибки.