Полный конструктор, если по какой-то причине вы не пытаетесь избежать использования исключений в вашей кодовой базе.
Я не буду вдаваться в аргументы за и против запрета всех исключений, но, например, в C ++, если вы не везде используете nothrow new, то вы не избегаете всех исключений, поэтому специальный случай не делает ' т применяется.
Возвращаясь к более независимой от языка территории, вы можете возразить, что «исключения предназначены только для исключительных случаев», но также «что отказ конструктора не является исключительным». Я не буду вдаваться в аргументы за или против этого, но у вас останется два варианта:
1) Установите флажок «сбой» на объекте, если конструкция не удалась, и вызывающие стороны должны проверить это (либо явно, либо это проверено в других функциях, которые ведут себя по-разному в зависимости от того, установлен ли он). Потоки файлов C ++ делают это с помощью конструктора, который принимает имя файла. Это неприятно для вызывающего, но меньше неприятностей, чем двухэтапное строительство.
2) Иметь вспомогательный объект для выполнения операций, которые могут завершиться ошибкой, но которые не должны быть исключениями, и заставить вызывающих использовать это. То есть заменить:
MyObj(a,b,c); // might throw
с
MyArgs args(a,b,c);
// optionally, if caller doesn't want an exception
if (!args.ok()) handle_the_error();
MyObj(args);
Затем в конструкторе, который принимает MyArgs, MyObj также может вызвать args.ok()
и вызвать исключение, если это не так. Один класс может предложить оба конструктора (или фабричные методы, если ваш язык не позволяет использовать несколько конструкторов), и позволить вызывающей стороне решить.
По сути, если вы хотите избежать исключения, то вызывающему абоненту придется где-то вручную проверять успешность. Лично я считаю, что если причина неудачи сводится к плохим аргументам, то лучше проверить заранее. Очевидно, что файловые потоки не могут этого сделать, потому что, является ли аргумент «плохим» или нет, может измениться, если файловая система изменяется между проверкой и конструктором. Таким образом, у вас нет выбора, кроме как проверить потом. Это все же лучше, чем двухэтапное строительство.
Если вам абсолютно необходимо двухэтапное построение самого объекта, то я думаю, что лучше скрыть это в заводском методе. Предполагая, что ваш язык допускает какое-то «ноль» для обозначения ошибок, то есть