Читать «Полный справочник по С++» онлайн - страница 428

Герберт Шилдт

StrType::StrType() {

size = 1; II Создаем место для нулевого символа, try {

р = new char[size];

} catch (bad_alloc xa) {

cout « "Ошибка при распределении памяти\п"; exit(1) ;

}

strcpy(p, "");

}

// Инициализация с помощью строки, взятой в кавычки.

StrType::StrType(char *str) {

size = strlen(str) +1; // Создаем место для нулевого символа try {

р = new char[size];

} catch (bad_alloc xa) {

cout << "Ошибка при распределении памяти\п"; exit(1) ;

}

strcpy(p, str);

}

// Инициализация с помощью объекта класса StrType.

StrType::StrType(const StrType &o) { size = o.size; try {

p = new char[size];

} catch (bad_alloc xa) {

cout « "Ошибка при распределении памяти\п" exit(l);

}

strcpy(p, о.p);

}

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

Когда объект класса StrType инициализируется строкой, взятой в кавычки, сначала определяется размер строки. Затем с помощью оператора new выделяется достаточный объект памяти, и строка инициализации копируется в область памяти, адресуемую указателем р.

Процедура инициализации объекта класса StrType другим объектом этого типа практически совпадает с процедурой инициализации объекта строкой, взятой в кавычки. Этот вариант конструктора класса StrType является конструктором копирования. Он вызывается каждый раз, когда создаваемый объект инициализируется другим объектом класса StrType. Это значит, что он вызывается как при создании временных объектов, так и при передаче объектов типа StrType в качестве параметров функции. (Конструкторы копирования рассматривались в главе 14.)

Таким образом, следующие три объявления являются вполне допустимыми.

I StrType x("my string"); II Применяется строка, взятая в кавычки. StrType у(х); II Используется другой объект типа StrType.

StrType z; II Явная инициализация не выполняется.

Деструктор класса StrType просто освобождает память, на которую ссылается указатель р.

—I Ввод и вывод строк

Поскольку строки часто вводятся и выводятся, в классе strType предусмотрены перегруженные версии операторов “<<” и

II Вывод строки.

ostream &operator«(ostream &stream, StrType &o)

{

stream « o.p;

return stream;

II Ввод строки.

'istream &operator>>(istream &stream, StrType &o)

{

char t[255]; II Размер выбран произвольно -

// при желании его можно изменить.

int len;

stream.getline(t, 255);

len = strlen(t) + 1;

if(len > o.size) { delete [] o.p; try {

o.p = new char[len];

} catch (bad_alloc xa) {

cout << "Ошибка при распределении памяти\п"; exit(1);

}

o.size = len;

)

StrCpy(O.p, t);

return stream;

Как видим, операция вывода строки очень проста. Однако следует обратить внимание, что параметр о передается по ссылке. Поскольку объекты класса strType довольно велики, их эффективнее передавать по ссылке, а не по значению. По этой причине все параметры, имеющие тип StrType передаются только по ссылке. (Разрабатывая функцию, параметрами которой являются объекты класса strType, следует иметь в виду это обстоятельство.)