Страницы

Поиск по вопросам

воскресенье, 2 февраля 2020 г.

Чем опасно самоприсваивание в своем реализуемом классе?

#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; } Тут проверку присваивания себе просто некуда воткнуть... :)

Комментариев нет:

Отправить комментарий