#include
using namespace std;
class MyString
{
private:
char* Buffer;
-7 .
public:
// Конструктор
MyString(const char* Initiallnput)
1 1 : {
if(Initiallnput != NULL)
-3:{
Buffer = new char [strlen(Initiallnput) + 1];
strcpy(Buffer, Initiallnput);
}
else
Buffer = NULL;
222 ЗАНЯТИЕ 9. Классы и объекты
}
// Деструктор: освобождает буфер, зарезервированный в
конструкторе
-MyString()
22: {
cout « "Invoking destructor, clearing up" « endl;
if (Buffer != NULL)
delete [] Buffer;
}
27:
int GetLengthO
{
return strlen(Buffer);
}
32:
const char* GetStringO
{
return Buffer;
}
}; // конец класса MyString
int main()
{
MyString SayHello("Hello from String Class");
cout « "String buffer in MyString is " « SayHello.GetLength();
cout « " characters long" « endl;
44:
cout « "Buffer contains: ";
cout « "Buffer contains: " « SayHello.GetString() « endl;
}
Результат
String buffer in MyString is 23 characters long Buffer contains: Hello from String Class Invoking destructor, clearing up
Анализ
Этот класс в основном инкапсулирует строку в стиле С в переменной
M y S trin g : : B u f f e r и освобождает вас от задач резервирования и освобождения памяти, осущ ествляемых одинаково при каждой необходимости использовать строку. Особенно интересен код конструктора M y S trin g () в строках 10-19 и деструктора - M y S trin g () в строках 21-26. Конструктор требует передачи исходной строки, поскольку у него есть обя зательный входной параметр, а затем копирует ее в строку в стиле С B u f f e r после резер вирования памяти для нее в строке 14, где используется оператор s t r l e n для определения длины исходной строки. Для копирования в эту недавно зарезервированную область памя ти в строке 15 используется оператор s tr c p y . На случай, если пользователь класса в ка честве аргумента для параметра I n i t i a l l n p u t предоставит значение NULL, переменная M y S trin g : : B uf f е г также инициализируется со значением NULL (чтобы указатель не со держал случайное значение, которое может оказаться опасным при попытке использовать его для доступа к области памяти). Код деструктора гарантирует автоматическое осво бождение памяти, зарезервированной в конструкторе, и возвращ ение ее операционной
Конструктор копий 223
;истеме. Он проверяет, не содержит ли переменная M y S trin g : : B u f f e r значение NULL,
если это не так, то выполняет для нее оператор d e l e t e [ ], дополняя оператор new в кон-гтрукторе. Обратите внимание, что нигде в функции m ain () не применяются операторы -ew или d e l e t e . Этот класс не только абстрагировал реализацию, но и гарантировал при ~ом техническую правильность освобождения зарезервированной памяти. Деструктор -M y S trin g () вызывается автоматически при возвращении к функции m ain (), и это де монстрирует вывод, поскольку в деструкторе выполняется оператор c o u t.
Классы, облегчающие работу со строками, являются одним из многих примеров ис пользования деструктора. На занятии 26, “Понятие интеллектуальных указателей”, вы •знаете, что деструкторы играют критически важную роль в работе с указателями более ложным способом.
-РИМЕЧАНИЕ
|
Деструкторы не могут быть перегружены. У класса может быть только один де
|
|
структор. Если вы забудете реализовать деструктор, компилятор создаст и вы
|
|
зовет фиктивный деструктор, т.е. пустой деструктор, который не осуществляет
|
|
никакого освобождения зарезервированной динамической памяти.
|
Do'stlaringiz bilan baham: |