5.2.4 Инициализация

5.2.4 Инициализация

Использование для обеспечения инициализации объекта класса функций вроде set_date() (установить дату) неэлегантно и чревато ошибками. Поскольку нигде не утверждается, что обект должен быть инициализирован, то программист может забыть это сделать, или (что приводит, как правило, к столь же рарушительным последствиям) сделать это дважды. Есть более хроший подход: дать возможность программисту описать функцию, явно предназначенную для инициализации объектов. Поскольку такая функция конструирует значения данного типа, она назывется конструктором. Конструктор распознается по тому, что имеет то же имя, что и сам класс. Например:

class date (* // ... date(int, int, int); *);

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

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

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

class date (* int month, day, year; public: // ... date(int, int, int); // день месяц год date(char*); // дата в строковом представлении date(int); // день, месяц и год сегодняшние date(); // дата по умолчанию: сегодня *);

Конструкторы подчиняются тем же правилам относительно типов параметров, что и перегруженные функции (#4.6.7). Если конструкторы существенно различаются по типам своих парамеров, то компилятор при каждом использовании может выбрать правильный:

date today(4); date july4(«Июль 4, 1983»); date guy(«5 Ноя»); date now; // инициализируется по умолчанию

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

Размножение конструкторов в примере с date типично. При разработке класса всегда есть соблазн обеспечить «все», покольку кажется проще обеспечить какое-нибудь средство просто на случай, что оно кому-то понадобится или потому, что оно изящно выглядит, чем решить, что же нужно на самом деле. Поледнее требует больших размышлений, но обычно приводит к программам, которые меньше по размеру и более понятны. Один из способов сократить число родственных функций – использвать параметры со значением по умолчанию, пример. В случае date для каждого параметра можно задать значение по умолчнию, интерпретируемое как «по умолчанию принимать: today» (сегодня).

class date (* int month, day, year; public: // ... date(int d =0, int m =0, int y =0); date(char*); // дата в строковом представлении *);

date::date(int d, int m, int y) (* day = d ? d : today.day; month = m ? m : today.month; year = y ? y : today.year; // проверка, что дата допустимая // ... *)

Когда используется значение параметра, указывающее «брать по умолчанию», выбранное значение должно лежать вне множества возможных значений параметра. Для дня day и месяца mounth ясно, что это так, но для года year выбор нуля неочвиден. К счастью, в европейском календаре нет нулевого года . Сразу после 1 г. до н.э. (year==-1) идет 1 г. н.э. (year==1), но для реальной программы это может оказаться слишком тонко.

Объект класса без конструкторов можно инициализировать путем присваивания ему другого объекта этого класса. Это моно делать и тогда, когда конструкторы описаны. Например:

date d = today; // инициализация посредством присваивания

По существу, имеется конструктор по умолчанию, опредленный как побитовая копия объекта того же класса. Если для класса X такой конструктор по умолчанию нежелателен, его моно переопределить конструктором с именем X(X amp;). Это будет осуждаться в #6.6.

Поделитесь на страничке

Следующая глава >

Похожие главы из других книг:

Инициализация Winsock

Из книги автора

Инициализация Winsock Winsock API поддерживается библиотекой DLL (WS2_32.DLL), для получения доступа к которой следует подключить к программе библиотеку WS_232.LIB. Эту DLL следует инициализировать с помощью нестандартной, специфической для Winsock функции WSAStartup, которая должна быть первой из


Инициализация параметров

Из книги автора

Инициализация параметров int pthread_mutexattr_init(const pthread_mutexattr_t* attr);Функция инициализирует структуру атрибутов мьютекса, на которую указывает параметр attr. Тип данных pthread_mutexattr_t определен в файле <pthread.h> (производный от типа sync_attr_t, который в свою очередь определен в файле


Инициализация мьютекса

Из книги автора

Инициализация мьютекса int pthread_mutex_init(pthread_mutex_t* mutex, const pthread_mutexattr_t* attr);Структура данных pthread_mutex_t определена в файле <pthread.h> (производный тип от типа sync_t, который в свою очередь определен в файле <target_nto.h>) и имеет следующий вид:struct _sync_t { /* Счетчик для рекурсивного


R.12.6 Инициализация

Из книги автора

R.12.6 Инициализация Объект класса без конструкторов, без частных или защищенных членов, без виртуальных функций и без базовых классов можно инициализировать с помощью списка инициализаторов (§R.8.4.1). Объект класса с конструктором должен инициализироваться или иметь


Шаг 12 - Двухэтапная инициализация.

Из книги автора

Шаг 12 - Двухэтапная инициализация. Когда мы создаем нестековый экземпляр, то пишем такой код:CClass* cc = new CClass();Попробуем поразбираться. new - это глобальный оператор с определением:void* operator new (size_t bytes);Он получает от компилятора количество байт, необходимое для хранения объекта,


Инициализация структуры

Из книги автора

Инициализация структуры      Мы видели, как инициализируются переменные и массивы: int count = 0;static int fibo[ ]={0, 1, 1, 2, 3, 5, 8};Можно ли инициализировать и структурную переменную? Да, если структурная переменная будет внешней или статической. Здесь следует иметь в виду, что


5.2.2. Инициализация семафоров

Из книги автора

5.2.2. Инициализация семафоров Выделение и инициализация семафора — две разные операции. Чтобы проинициализировать семафор, вызовите функцию semctl(), задав второй аргумент равным нулю, а третий аргумент — равным константе SETALL. Четвертый аргумент должен иметь тип union semun, поле


Инициализация

Из книги автора

Инициализация Переменной в объявлении может быть присвоено начальное значение посредством инициализатора. Записи инициализатора в объявлении предшествует знак равенства=<инициализатор>Можно инициализировать переменные любого типа. Функции не инициализируются.


7.9.2. Инициализация и присваивание

Из книги автора

7.9.2. Инициализация и присваивание Вспомним, что имя массива без указания индекса элемента интерпретируется как адрес первого элемента. Аналогично имя функции без следующих за ним скобок интерпретируется как указатель на функцию. Например, при вычислении


14.1. Инициализация класса

Из книги автора

14.1. Инициализация класса Рассмотрим следующее определение класса:class Data {public:int ival;char *ptr;};Чтобы безопасно пользоваться объектом класса, необходимо правильно инициализировать его члены. Однако смысл этого действия для разных классов различен. Например, может ли ival


14.6. Почленная инициализация A

Из книги автора

14.6. Почленная инициализация A Инициализация одного объекта класса другим объектом того же класса, как, например:Account oldAcct( " Anna Livia Plurabelle" );Account newAcct( oldAcct );называется почленной инициализацией по умолчанию. По умолчанию - потому, что она производится автоматически, независимо


5.2.4 Инициализация

Из книги автора

5.2.4 Инициализация Использование для обеспечения инициализации объекта класса функций вроде set_date() (установить дату) неэлегантно и чревато ошибками. Поскольку нигде не утверждается, что обект должен быть инициализирован, то программист может забыть это сделать, или (что


6.6 Присваивание и Инициализация

Из книги автора

6.6 Присваивание и Инициализация Рассмотрим очень простой класс строк string:struct string (* char* p; int size; // размер вектора, на который указывает pstring(int sz) (* p = new char[size=sz]; *) ~string() (* delete p; *) *);Строка – это структура данных, состоящая из вектора сиволов и длины этого вектора. Вектор


Инициализация

Из книги автора

Инициализация На этапе инициализации в зависимости от входных параметров устанавливаются переменные состояния, необходимые для валидации пути сертификации [70]. В переменных состояния сохраняются различные ограничения, учитываемые при валидации пути. Переменные