Бьерн Страуструп - Абстракция данных в языке С++ - Конструктор и перегруженные функции

ОГЛАВЛЕНИЕ

 

Конструктор и перегруженные функции

      Использование функцийа тип s e t _ d a t e для
  инициализации объектов класса не элегантно и чревато ошибками.
  Так как нигде не утверждается, что объект должен быть
  инициализирован; программист может забыть сделать это или часто
  с равно плачевным результатом, сделать это дважды. Лучший подход
  состоита в том, чтобы позволить программисту объявить функцию
  явно предназначенную для инициализации объекта. Так как такая
  функция конструирует значения данного типа, он называется
  конструктором данного класса и опознается в языке благодаря тому,
  что имеет то же имя, что и сам класс. Например:

      class date { 
            . . .
            date (int, int, int);
      };

      Если класс имеет конструктор, все объекты этого класса
  должны быть инициализированы:

      date today = date (23,  6, 1983); 
      date xmas (25, 12, 0); /* правильная сокращенная форма */
      date jily4 = today;
      date my_birthday;/* неправильно, отсутствует инициализация */

      Часто желательно предоставить несколько способов
  инициализации объектов класса. Это можно сделать путем
  предоставления нескольких конструкторов. Например:

      class date { 
      . . .
      date (int, int, int); /* день месяц год */
      date (char*); /* дата в символьном виде */
      date (int); /* день,месяц и год подразумеваются текущими */
      date (); /* умолчание: сегодня */
      };

      Поскольку функции-конструкторы различаются типами своих
  аргументов, компилятора в каждом случае в состоянии выбрать
  правильную функцию:

      date today (4); 
      date july4 ("July 4, 1983");
      date guy ("5 Nov");
      date now; /* инициализация по умолчанию */

      Применение конструкторов не ограничивается инициализацией
  они могут быть использованы везде, где необходимо иметь объект
  данного класса:

      date us_date (int  month, int day, int year) 
      {
            return date (day, month, year);
      }
      . . .
      some_function (us_date (12, 24, 1983));
      some_function ( date (24, 12, 1983));

      Если несколько функций объявлены с одинаковым именем
  говорятб что это имя перегруженою Использование перегруженных
  имен функций не ограничивается случаем конструкторов. Однако для
  несоставляющих функций их описания должны предваряться указанием,
  что имя будет перегружено, например:

      overload print; 
      void print (int);
      void print (char*);

      или, возможно, сокращенно:

      overload void print  (int), print (char*); 

      С точки зрения компилятора, единственная вещь, общая для
  множества функций с одним именнем
  говорятб что это имя перегруженою Использование перегруженных
  имен функций не ограничивается случаем конструкторов. Однако для
  несоставляющих функций их описания должны предваряться указанием,
  что имя будет перегружено, например:

      overload print; 
      void print (int);
      void print (char*);

      или, возможно, сокращенно:

      overload void print  (int), print (char*); 

      С точки зрения компилятора, единственная вещь, общая для
  множества функций с одним именмер, вышеприведенное описание
  простого конструктора для класса d a t e.
      Для аргументов функции с перегруженными именами правила
  преобразования типов язык С применяются не полностью.
  Преобразования, которые могут исказить информацию, не d o u b l e.
Возможно, однако, предусмотреть разные функции для
  целого и вещественного типов. Например:

      overlood print (int),  print (double); 

      Список функций с перегруженным именем будет просматриваться
  по порядку до появления совпадения, таким образом p ri n t (l)
  будет вызывать функцию p r i n t для целого типа аргумента, а
  p r i n t (l,0) - для функции p r i n t с плавающей точкой.
  Если же порядок описаний будет изменен, оба обращения к функции
  вызовут функцию p r i n t с плавающей точкой с вещественным
  (d o u b l t) представлением аргумента l.