Присваивание и инициализация


Рассм-м простой класс строк string: struct string { char* p;
int size; // размер вектора, на который // указывает p string(int sz) { p = new char[size=sz]; } ~string() { delete p; } }; Строка-это стр-ра д-ых, сост-ая из вектора символов и длины этого вектора.Вектор созд-ся констр-ром и уничт-ся дестр-ром.Но это может привести к неприятностям. Например: void f(){string s1(10);string s2(20);s1=s2;} будет размещать два в-ра симв-в,а присв-ие s1=s2 будет портить указатель на один из них и дублир-ть др-ой. На выходе изf() для s1 и s2 будет вызыв-ся дестр-р и уничтожать один и тот же вектор с непредсказуемо разрушительными последствиями. Реш-ие этой проблемы сост-т присв-ие объектов типа string соотв-им образом:
struct string{char* p;
int size; // размер вектора,на к-ый ук-ет p string(int sz) { p = new char[size=sz]; } ~string() { delete p; } void operator=(string&) }; void string::operator=(string& a) { if (this == &a) return; // остерегаться
s=s; delete p; p=new char[size=a.size];
strcpy(p,a.p);} Это опр-ие string гар-ет, и что предыд-ий пр-р будет работать как предполагалось. Но неб-ое изм-ие f() приведет к появл-ию той же проблемы в новом облике: void f(){string s1(10); s2 = s1;} Теперь созд-ся только одна строка, а уничт-ся две. К неиниц-ому объекту опер-ия присв-ия, опр-ая пользов-ем,не прим-ся. Что не жел-но, т.к. из опр.operate=…сл-ет,что ук-ль р сод-л бы неопр-ое и совер-но случ-ое знач-ие. Часто
опер-ия присв-ия полаг-ся на то, что ее арг-ты иниц-ны. Для такой иниц-ии, как здесь,это не так по опр-ию. След-но,нужно опр-ть анал-ую,но отд-ую ф-ию: struct string { char* p;
int size;//размер в-ра,на к-ый ук-ет p string(int sz) { p = new char[size=sz]; } ~string() { delete p; } void operator=(string&); string(string&);
};
void string::string(string& a) {
p=new char[size=a.size]; strcpy(p,a.p);}
Для типа X иниц-ию тем же типом X обраб-ет констр-рX(X&). Присв-ие и иниц-ия-разные д-ия, сущ-но при описании дестр-ра. Если класс X имеет констр-р X(X&),вып-ий нетрив-ую работу вроде освобождения памяти, то скорее всего потреб-ся полный комплект ф-ий для полного избежания побит-го копир-я объектов:
class X {// …
something);//констр-р:создает объект
X(&X);//констр-р:коп-ет в иниц-ии operator=(X&);//присв-ие: чистит и копирует ~X(); // деструктор: чистит
};

Загрузка...