Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Шпоры / ООП(Тимофеев) / ООП-Тимофеев.doc
Скачиваний:
41
Добавлен:
16.04.2013
Размер:
328.19 Кб
Скачать

Конструкторы как преобразования

Конструктор с единственным параметром автоматически является функцией преобразования, если только он не объявлен с ключевым словом explicit. Рассмотрим следующий класс, назначение которого — напечатать невидимые символы с их представлением ASCII; например, код с восьмеричным номером 07 — это звонок (звуковой сигнал).

class pr_char { public: pr_char(int i = 0) : c(i % 128) {}

void print() const { cout <<rep[c];}

private: int c; static const char* rep(128]; };

const char* pr_char::rep[128] = { "nul", "soh", "stx",

.......

" w ", " x "," y ", "z ", "{"," | ", " } ", " ~", " de1"};int main ()

{ pr_char с ; for (int i = 0; i < 128; ++i) { с = i; //или: c=static_cast<pr_char>(i)

c.print() ; cout << endl ; } }

Конструктор выполняет автоматическое преобразование типа int в тип pr_char. Отметьте, что инструкция в цикле

c = i; как раз и заключает в себе это преобразование.

Создание динамического стека

Конструктор можно также использовать для выделения пространства из свободной памяти.

//Реализация ch_stack с конструктором

class ch_stack { public:

//открытый интерфейс для АТД ch_stack

explicit ch_stack(int size) : max_len(size), top(EMPTY)

{ assert(size > 0); s = new char[size]; assert(s != 0);}

void reset () { top = EMPTY; }

void push(char c) { s[++top] = c; }

char pop() { return s[top--]; }

char top_of() const { return s[top]; }

bool empty() const { return (top = = EMPTY); }

bool full() const { return (top = = max_len - 1); }

private:

enum { EMPTY = -1 };

char* s; //было s[max_len]

int max_len;

int top;

};

Теперь клиент, использующий ch_stack, может выбрать требуемый размер. Пример объявления ch_stack с вызовом конструктора выглядит так:

ch_stack data(l000); //размещение 1000 элементов

ch_stack more_data(2 * n) ; //размещение 2*п элементов

Копирующий конструктор

Рассмотрим наш стек и подсчитаем, сколько раз встречается заданный символ. Можно многократно извлекать элементы из стека, проверяя каждый из них по очереди, до тех пор пока стек не будет пуст. Но что если мы хотим сохранить нетронутым содержимое стека? Вызываемые по значению параметры именно это и выполняют:

int cnt_char(char с, ch_stack s)

{int count = 0; while (! s.empty()) count += (c = = s.pop());

return count; }

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

ch_stack::ch_stack(const ch_stack&);

Классы с деструкторами

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

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

Соседние файлы в папке ООП(Тимофеев)