Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
ТП лекции Раздел 4.doc
Скачиваний:
16
Добавлен:
28.09.2019
Размер:
2.56 Mб
Скачать

Конструктор по умолчанию

Конструктор по умолчанию не имеет аргументов и используется при созда­нии неинициализированного объекта:

class MyClass{

public:

MyClass() { }

…..

// Остальные данные и методы

};

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

MyClass clObj;

Как и любая другая функция, конструкторы могут иметь аргументы со зна­чениями, заданными по умолчанию. При этом следует избегать неоднознач­ностей. Например, в случае определения класса

class MyClass{

public:

MyClass();

MyClass(int nArg = 0);

….

// Остальные данные и методы

};

может возникнуть неопределенность при вызове конструктора

MyClass clObjl (7); // можно — однозначно вызывается MyClass::MyClass(int)

MyClass cl0bj2; // нельзя; неоднозначно задано, какой конструктор

// следует вызывать — MyClass::MyClass(int)

// или MyClass::MyClass(int nArg = 0)

Конструктор копирования

Аргументом конструктора может быть и сам объект класса. Такой конструк­тор будет иметь следующий прототип:

MyClass::MyClass(MyClass &);

Такие конструкторы запускаются при копировании данных "старого" объек­та во вновь создаваемый:

MyClass clObjl(7) ;

MyClass clObjl = cl0bj2;

Если для класса конструктор копирования не определен, то компиля­тор сделает это сам.

4.6.4. Деструкторы классов.

Еще один метод, называемый деструктором, используется для освобождения памяти, занимаемой членами класса. Особенно важную роль играет деструктор в случае динамического выделения памяти из области heap. Как известно, такую память следует явно освобождать операцией delete. Если тело деструктора создано, то он сделает это автоматически, как только закончит работу функция, в которой определен объект данного класса. Он неявно вызывается в случае выхода программы из области действия объекта. Деструктор носит имя класса, в котором он определен, но перед его именем должен стоять символ ~. Например, описание А::~А(){}; задает деструктор класса А.

В отличие от конструкторов, деструктор класса не имеет аргументов и не может быть перегружен. Деструкторы вызываются строго в обратной последователь­ности вызова соответствующих конструкторов. Они вызываются автоматиче­ски при выходе объекта из блока, в котором были определены. Единствен­ным исключением из этого общего правила является случай, когда объект создается динамически из "кучи", путем вызова оператора new. В этом слу­чае для корректного удаления объекта необходимо явно выполнить оператор delete, который и вызовет необходимый деструктор.

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

// Простой пример, демонстрирующий

// последовательность вызовов конструкторов и деструкторов

#include <stdio.h>

#include <string.h>

// Объявляем класс

class Sample{

private: // К этим данным доступ возможен только посредством методов

// класса

char *strName;

public: // К этим данным доступ возможен из любого места программы

// Определяем простой конструктор

Sample (char *str) {

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

strcpy(strName, str);

printf("Entry in constructor for %s\n", strName);

}

// Определяем деструктор

~Sample(){

printf("Entry in destructor for %s\n", strName);

delete strName;

strName = 0;

}

};

// Определяем первый глобальный объект

Sample globall("global #1");

// "Глупая" функция, иллюстрирующая создание автоматического объекта

void SillyFunc(){

// Определяем объект, локальный для данной функции

Sample fnAuto("automatic function");

printf("Function SillyFunc()\n");

}

int main(int argc, char* argv[])

{

// Определяем первый локальный объект

Sample autol("automatic #1");

printf("Begin main()\n");

SillyFunc();

// Определяем второй локальный объект

Sample auto2("automatic #2");

printf("Continue main()\n");

return 0;

}

// Определяем второй глобальный объект

Sample global2("global #2");

Результаты работы программы:

Entry in constructor for global #1

Entry in constructor for global #2

Entry in constructor for automatic #1

Begin main()

Entry in constructor for automatic function

Function SillyFunc()

Entry in destructor for automatic function

Entry in constructor for automatic #2

Continue main()

Entry in destructor for automatic #2

Entry in destructor for automatic #1

Entry in destructor for global #2

Entry in destructor for global #1

Press any key to continue

Тема 4.7. Скрытие данных в классах Visual C++.