C++   ::   Хилл Мюррей

Страница: 212 из 357

Следовательно, нужно определить похожую, но другую, функцию, чтобы обрабатывать инициализацию:

struct string (* char* p; int size; // размер вектора, на который указывает p

string(int sz) (* p = new char[size=sz]; *) ~string() (* delete p; *) void operator=(string amp;); string(string amp;); *);

void string::string(string amp; a) (* p=new char[size=a.size]; strcpy(p,a.p); *)

Для типа X инициализацию тем же типом X обрабатывает конструктор X(X amp;). Нельзя не подчеркнуть еще раз, что присвивание и инициализация – разные действия. Это особенно сщественно при описании деструктора. Если класс X имеет контруктор X(X amp;), выполняющий нетривиальную работу вроде освобождения памяти, то скорее всего потребуется полный комлект функций, чтобы полностью избежать побитового копирования объектов:

class X (* // ... X(something); // конструктор: создает объект X( amp;X); // конструктор: копирует в инициализации operator=(X amp;); // присваивание: чистит и копирует ~X(); // деструктор: чистит *);

Есть еще два случая, когда объект копируется: как парметр функции и как возвращаемое значение. Когда передается параметр, инициализируется неинициализированная до этого пременная – формальный параметр. Семантика идентична семантике инициализации. То же самое происходит при возврате из фунции, хотя это менее очевидно. В обоих случаях будет применен X(X amp;), если он определен:

string g(string arg) (* return arg; *)

main() (* string s = «asdf»; s = g(s);

*) Ясно, что после вызова g() значение s обязано быть «asdf». Копирование значения s в параметр arg сложности не представляет: для этого надо взывать string(string amp;).

|< Пред. 210 211 212 213 214 След. >|

Java книги

Контакты: [email protected]