#cpp #указатели
Ниже пояснено что может появится висячий указатель, но я не совсем понимаю как это возможно // перегруженная операция =; предотвращает самоприсваивание const String fiString::operator=( const String &right ) { cout <<"operator= called" << endl; if ( &right != this ) // предотвратить самоприсваивание { delete [] sPtr; // предотвращает утечку памяти length = right.length; // новая длина строки setString( right.sPtr ); // вызвать вспомогательную функцию } // конец if else cout << "Attempted assignment of a String to itself" << endl; return *this; // разрешает каскадное присваивание } // конец функции operator=
Ответы
Ответ 1
Попробуйте выполнить код без 49 if ( &right != this ) // предотвратить самоприсваивание Что будет? Сначала удалится sPtr, а потом setString( right.sPtr ); где right.sPtr=this.sPtr уже удалено, то есть никакого string нету. Ясно, что информация потеряется.Ответ 2
В ответ на "как правильнее". Есть разные варианты. Вот, в качестве примера оператор присваивания строки String другой такой строке... явно ведь есть копирующий конструктор? Допишем еще функцию обмена "внутренностями" swap - т.е. если класс примерно class String { int length; char * sPtr; ... то это что-то вроде (для простоты не стал использовать стандартную ::swap: void String::swap(String& s) { int tmp = length; length = s.length; s.length = tmp; char * ptr = sPtr; sPtr = s.sPtr; s.sPtr = ptr; } тогда вот такой оператор присваивания String& operator=(const String& src) { String tmp(src); swap(tmp); return *this; } выполнит присваивание, не нуждаясь в проверке присваивания самому себе. Ее (эту проверку) можно добавить - для эффективности, но не для предотвращения ошибок. Можно копирование сделать неявным: String& operator=(const String src) { swap(src); return *this; } Тут проверку присваивания себе просто некуда воткнуть... :)
Комментариев нет:
Отправить комментарий