Если вы не используете исключения, вы не должны использовать конструкторы (или не должны писать конструкторы, которые могут потерпеть неудачу), потому что, как вы заметили, нет способа сообщить об ошибке из конструктора, кроме как через исключение. Вы можете поочередно использовать заводскую функцию и использовать ее для отделения битов, которые могут выйти из строя, от битов, которые не могут
class myClass {
private:
char *m_malloced_buffer;
// disallow calling ctors/dtors directly
myClass(char *malloced_buffer) : m_malloced_buffer(malloced_buffer) {}
~myClass() { free(m_malloced_buffer); }
public:
static myClass *create()
{
char *buf = static_cast<char*>(malloc(100*sizeof(*mem)));
if(!buf) return NULL;
void *myClassRes = malloc(sizeof(myClass));
if(!myClassRes) return NULL;
new (myClassRes) myClass(buf); // placement new, uses existing memory to invoke the ctor
return static_cast<myClass*>(myClassRes);
}
static void destroy(myClass* val)
{
if(!val) return;
val->~myClass(); // explicitly invoke dtor
free(val); // deallocate memory
}
};
...
myClass *val = myClass::create();
if(val) { ... }
myClass::destroy(val);
В этом примере я использовал malloc и free, чтобы сделать все выделение, вы можете использовать new (std :: nothrow) и удалить так же легко. Вам нужно будет извлечь каждую операцию, которая может завершиться с ошибкой, из вашего ctor-компонента в заводскую функцию, чтобы вы могли проверять ошибки без использования исключений. Даже в этом простом примере вы можете видеть, что это огромная боль в шее. Вы говорите, что узнали, что «исключения не являются хорошим стилем кодирования» в комментарии, вы имеете в виду, что вы узнали что (будь то по инструкции с аргументированными аргументами и объяснениями или из опыта) или кто-то сказал, что «исключения не хороший стиль кодирования ", и вы приняли заявление как догму?
Использование инициализированного члена bool приводит к проблеме с объектом-зомби (см. http://www.parashift.com/c++-faq-lite/exceptions.html).