Сложная логика и конструктор не всегда хорошо сочетаются, и есть сильные сторонники против тяжелой работы в конструкторе (по причинам).
Кардинальное правило заключается в том, что конструктор должен давать полностью пригодный для использования объект.
class Vector
{
public:
Vector(): mSize(10), mData(new int[mSize]) {}
private:
size_t mSize;
int mData[];
};
Это не означает, что полностью инициализирован объект, вы можете отложить некоторые инициализации (думаю, что ленив) до тех пор, пока пользователь не должен думать об этом.
class Vector
{
public:
Vector(): mSize(0), mData(0) {}
// first call to access element should grab memory
private:
size_t mSize;
int mData[];
};
Если есть тяжелая работа, чтобы сделать, вы можете выбрать, чтобы продолжить метод строителя, который будет делать тяжелую работу до вызова конструктора. Например, представьте себе получение настроек из базы данных и создание объекта настройки.
// in the constructor
Setting::Setting()
{
// connect
// retrieve settings
// close connection (wait, you used RAII right ?)
// initialize object
}
// Builder method
Setting Setting::Build()
{
// connect
// retrieve settings
Setting setting;
// initialize object
return setting;
}
Этот метод построения полезен, если отложить строительство объекта дает значительную выгоду. Из примера, если объекты захватывают много памяти, откладывание памяти после задач, которые могут потерпеть неудачу, может быть плохой идеей.
Этот метод строителя подразумевает частный конструктор и публичный (или друг) строитель. Обратите внимание: наличие частного конструктора накладывает ряд ограничений на обычаи, которые могут выполняться для класса (например, не может храниться в контейнерах STL), поэтому вам может понадобиться объединить другие шаблоны. Именно поэтому этот метод следует использовать только в исключительных обстоятельствах.
Возможно, вы захотите также изучить, как тестировать такие объекты, если вы зависите от внешней вещи (файла/БД), подумайте об Injection Dependency, это действительно помогает с Unit Testing.
http://gotw.ca/gotw/066.htm – DumbCoder
Я думаю, что это плохая идея добавлять в классы такие вещи, как 'init()' и 'cleanup()'. Это кричит об ошибках. Вы не можете быть уверены, что класс был 'init()' ed. Вы можете добавить функции для проверки этого, но это делает его еще более сложным. – jwueller
@ DumbCoder: Извините, но я не совсем понял. Насколько я понимаю, статья, которую вы связали, говорит об исключениях. – tyrondis