Студопедия

Главная страница Случайная страница

Разделы сайта

АвтомобилиАстрономияБиологияГеографияДом и садДругие языкиДругоеИнформатикаИсторияКультураЛитератураЛогикаМатематикаМедицинаМеталлургияМеханикаОбразованиеОхрана трудаПедагогикаПолитикаПравоПсихологияРелигияРиторикаСоциологияСпортСтроительствоТехнологияТуризмФизикаФилософияФинансыХимияЧерчениеЭкологияЭкономикаЭлектроника






Механизмы создания и уничтожения объектов






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

В C++ предусмотрены специальные функции-члены класса, которые в большинстве случаев вызываются не программистом, а компилятором языка. Функции, выполняющие инициализацию объектов абстрактных типов, называются конструкторами, а функции, управляющие уничтожением объектов - деструкторами.

Конструктор - это просто специальная функция-член класса, отличительной чертой которой является то, что ее имя всегда совпадает с именем класса. Например, для класса String конструктор может быть определен как встраиваемая функция:

class String {

char * str; int row, col; public:

/ /Конструктор: String (char* s) { str = new char[strlen(s)+1];

strcpy(str, s);

}

};

либо как внешняя функция:

class String {

char * str;

int row, col; public:

//Объявление конструктора:

String (char* s);

};

//Внешнее определение конструктора:

{String:: String (char * s)

str = new char [strlen(s } +1];

strcpy (str, s); }

Конструктор, как и обычная функция, может принимать аргументы. В нашем примере в теле конструктора:

• динамически выделяется память для строки;

• передаваемая в качестве аргумента строка копируется по адресу str (становится значением данного-члена класса);

Невозможно создать объект абстрактного типа без вызова конструктора. Таким образом, такой объект всегда будет инициализирован. Для конструктора не указывается тип результата(даже void). Конструктор вызывается неявно каждый раз при объявлении объекта класса или создании его операцией new. Например, объявление

String s1 (" Строка");

создает объект s 1 и одновременно инициализирует его.

Конструктор без аргументов, жестко задаются все данные объекта - строка и позиция ее вывода на экран: */

String:: String () {

str = new char [sizeof(ХХХХХХХХХ")];

strcpy (str, " XXXXXXXXX");

row =10;

col = 35;

}

/*

Конструктор инициализирует саму строку значением, переданным в качестве аргумента; позиция вывода строки на экран задается жестко в конструкторе: */

String:: String (char* s) {

str = new char [strlen(s)+1];

strcpy (str, s);

row = 10; •, *

col = 35; }

/*

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

void f ()

{

String s1;

String s2(" Вторая строка");

String s3{''Третья строка", 10, 15);

}

Часто при разработке классов появляется соблазн предусмотреть конструкторы на все случаи жизни, но такой подход нельзя считать рациональным. В данном случае принцип " разумной достаточности" очень полезен -лучше потратить время на обдумывание небольшого числа гибких и универсальных конструкторов, чем написание большого количества специфических и, следовательно, редко используемых. Очень полезным средством в этом отношении является использование аргументов по умолчанию. Пример:

class String {

char * str;

int row, col; public:

//Объявление конструктора:

String (char * = " XXXXXXXX”, int = 5, int = 5);

};

//Определение конструктора:

String:: String (char * s, int x, int y)

{

str = new char[strlen(s)+1];

strcpy(str, s);

row = x; col - y; }

Отличие конструктора от остальных функций-членов класса заключается в следующем:

• конструктор имеет строго определенное имя, совпадающее с именем класса;

• конструктор не имеет явно указанного возвращаемого значения;

• вызов конструктора происходит автоматически во время объявления объекта абстрактного типа (либо при создании объекта операцией new), никаким другим способом вызвать конструктор нельзя.






© 2023 :: MyLektsii.ru :: Мои Лекции
Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав.
Копирование текстов разрешено только с указанием индексируемой ссылки на источник.