Не сочтите за RTFM, но Мейерс С. Эффективное использование С++. 50(55) советов... (и бумажный, и e-лектронный вариант найти несложно; правда, необходимо отличать от второй книги автора Наиболее эффективное использование С++. 35 советов...). Имеется отдельная глава "Конструкторы, деструкторы и операторы присваивания", букаф немного. Думаю, в этой книге ответы найти быстрее и проще, чем на форуме; кроме того, там есть ответы на вопросы, которые могли и не придти в голову.
Здравствуйте, sanx, Вы писали:
S>Не понимаю, почему просто не разрушать объект, вызывая его деструктор, и после вызывать конструктор копирования. Зачем нужно переопределять оператор "="? Понимаю еще "=+" и подобные. Но просто "=" — это же по сути отказ от старого объекта? Тем более что разумно автоматически возвращать сам этот объект в операторе "=", а с этим компилятор должен справиться без проблем. То есть 1) Разрушаем старый объект, 2) Вызываем нужный конструктор копирования, 3) Если нужно, возвращаем новый объект (если у нас a = b = c). Почему же тогда не так?
потому что в общем случае убить и создать дороже, чем скопировать.
Например, у тебя уже выделена память — и что, ее грохать и выделять по новой?
Здравствуйте, jazzer, Вы писали:
J>Я так понимаю, sanx имел в виду, чтоб это делалось самим компилятором по умолчанию (который "почти всегда" знает про все эти пляски) и оператора присваивания вообще не было в языке в принципе.
Доводы те же самые. Мысленно представь, что X::operator= был создан компилятором, и создан именно так: dtor-cctor.
После чего устраиваем провокацию и получаем кучу проблем на ровном месте.
В роли провокации выступают
— срезка, я уже показал как
— бросок исключения в cctor
Причём, если исключение возникает в операторе присваивания — мы можем получить несогласованное состояние объекта (а можем и логически согласованное), но хотя бы на самом примитивном уровне оно останется определённым. А после исключения из конструктора — состояние не просто несогласованное, а его нет как такового.
Не понимаю, почему просто не разрушать объект, вызывая его деструктор, и после вызывать конструктор копирования. Зачем нужно переопределять оператор "="? Понимаю еще "=+" и подобные. Но просто "=" — это же по сути отказ от старого объекта? Тем более что разумно автоматически возвращать сам этот объект в операторе "=", а с этим компилятор должен справиться без проблем. То есть 1) Разрушаем старый объект, 2) Вызываем нужный конструктор копирования, 3) Если нужно, возвращаем новый объект (если у нас a = b = c). Почему же тогда не так?
Здравствуйте, jazzer, Вы писали:
J>потому что в общем случае убить и создать дороже, чем скопировать. J>Например, у тебя уже выделена память — и что, ее грохать и выделять по новой?
Действительно. Как то не подумал. Да и еще вспомнил, о возможности просто хранить ссылку на тот же объект, и копировать только если будет изменение.
Здравствуйте, Кодт, Вы писали:
К>Здравствуйте, sanx, Вы писали:
S>>Не понимаю, почему просто не разрушать объект, вызывая его деструктор, и после вызывать конструктор копирования.
К>Потому что это ведёт к неопределённому поведению, в общем случае.
Я так понимаю, sanx имел в виду, чтоб это делалось самим компилятором по умолчанию (который "почти всегда" знает про все эти пляски) и оператора присваивания вообще не было в языке в принципе.
Здравствуйте, Кодт, Вы писали:
К>Причём, если исключение возникает в операторе присваивания — мы можем получить несогласованное состояние объекта (а можем и логически согласованное), но хотя бы на самом примитивном уровне оно останется определённым. А после исключения из конструктора — состояние не просто несогласованное, а его нет как такового.
Да, ты прав, исключение из конструктора убивает всю идею на корню.