Оставляя в стороне, что вы должны, если возможно, исправить вызывающий код, чтобы исключение было в порядке, вы можете использовать двухфазную конструкцию:
struct foo_class {
foo_class() { } // default constructor cannot fail
Errmsg nothrow_init(/* other params */) throw() {
/* initialize other parameters */
}
foo_class(/* other params */) {
if (nothrow_init(/* other params */) != ERRMSG_OK) {
throw something;
}
}
};
Теперь код, использующий исключения, может вызывать мульти-arg конструктор (и получить объект в состоянии готовности к использованию), тогда как код, исключающий исключение, может вызвать конструктор по умолчанию, за которым следует nothrow_init
(и согласиться с тем фактом, что если nothrow_init
не удастся, у них будет непригодный объектв их руках, и они несут ответственность за то, чтобы они не использовали его.)
В будущем, когда вы переведете другие части своей кодовой базы в состояние использования исключений, вы обнаружите, что кодв init
называет вещи, которые могут сами выбросить.В этот момент вы можете начать перемещать код, так что nothrow_init
вызывает функцию init
, которая может генерировать, но перехватывает любые исключения и превращает их в коды ошибок.Если предположить, что это внутренний класс, то в конечном итоге ничто не будет использовать nothrow_init
, и вы можете удалить его.