Программирование. Принципы и практика использования C++ Исправленное издание, стр. 242
Конструкторы, имеющие аргументы, сильно зависят от класса, в котором они реализованы. Остальные операции имеют более или менее стандартную структуру.
Как понять, что в классе необходим конструктор по умолчанию? Он требуется тогда, когда мы хотим создавать объекты класса без указания инициализатора. Наиболее распространенный пример такой ситуации возникает, когда мы хотим поместить объекты класса в стандартный контейнер, имеющий тип
vectorintstringvector<int>vector<double> vi(10); // вектор из 10 элементов типа double, // каждый из них инициализирован 0.0vector<string> vs(10); // вектор из 10 элементов типа string, // каждый из них инициализирован ""vector<vector< int> > vvi(10); // вектор из 10 векторов, // каждый из них // инициализирован конструктором vector()Итак, иметь конструктор по умолчанию часто бывает полезно. Возникает следующий вопрос: а когда именно целесообразно иметь конструктор по умолчанию? Ответ: когда мы можем установить инвариант класса с осмысленным и очевидным значением по умолчанию. Для числовых типов, таких как
intdouble0double0.0string""vectorTT()double()0.0string()""vector<int>()vectorint
deletedelete[]
vector
18.3.1. Явные конструкторы
Конструктор, имеющий один аргумент, определяет преобразование типа этого аргумента в свой класс. Это может оказаться очень полезным. Рассмотрим пример.
class complex {public: complex(double); // определяет преобразование double в complex complex(double,double); // ...};complex z1 = 3.18; // OK: преобразует 3.18 в (3.18,0)complex z2 = complex(1.2, 3.4);
vectorintintvectorclass vector { // ...vector(int); // ...};vector v = 10; // создаем вектор из 10 элементов типа doublev = 20; // присваиваем вектору v новый вектор // из 20 элементов типа double to vvoid f(const vector&);f(10); // Вызываем функцию f с новым вектором, // состоящим из 10 элементов типа double
explicitclass vector {