Хм... приватный конструктор - это, видимо, запрет на копирование.
Опасность, как я понимаю, в том, что если в полях класса есть хоть одна ссылка, то при конструкторе копирования по умолчанию скопируется сама ссылка. Т.е. 2 или более объекта будут ссылаться на одну и ту же область памяти. Так?
Чем чревато до delete, думаю, объеснять не надо. Ну а по delete просто будет сегфолт (это кстати хорошо - потому что позволит выявить проблему сразу).
> Опасность, как я понимаю, в том, что если в полях класса есть хоть одна ссылка, то при конструкторе копирования по умолчанию скопируется сама ссылка.
Совсем не правильно. В корне. Ты думаешь об устройстве объекта - но тебе же не нем не говорили. Значит надо думать о нем, как о черном ящике.
Отсутствие конструктора копировании - это отсутствие семантики копирования (например, у главного объекта приложения). В том числе это отсутвие семантики значения.
А уж там ссылки, указатели - это все проблемы разработчика класса объекта, которые легко решаются.
Хм... приватный конструктор - это, видимо, запрет на копирование.
Опасность, как я понимаю, в том, что если в полях класса есть хоть одна ссылка, то при конструкторе копирования по умолчанию скопируется сама ссылка. Т.е. 2 или более объекта будут ссылаться на одну и ту же область памяти. Так?
так, только не забываем что при этом область памяти на которую до копирования ссылки указывал указатель станет безхозной (orphaned) :) то есть до кучи будет утечка памяти
Чем чревато до delete, думаю, объеснять не надо. Ну а по delete просто будет сегфолт (это кстати хорошо - потому что позволит выявить проблему сразу).
ну насчёт того насколько segfault - это хорошо я не знаю, но вот с выявлением могут быть проблемы :) потому как delete имеет обыкновение в деструкторах вызываться и вот Ваш код отработал, началось удаление и, ВНЕЗАПНО, всё падает... если код наверченый - пойди разберись :) не в том смысле что не разберёшься, а в том что время тратится -> скорость разработки dramatically decreases... а теперь если во втором классе какой-то «умный» человек забыл поставить delete то у Вас будет просто течь память, а падать ничего не будет... тоже весело, правда?
и это, заметьте, даже не нюанс, а просто известный всем факт... :) так что пока человек научается писать нормально программы на c++ проходит не один год, это в отличие от пресловутых java, python, c# и иже с ними
> и это, заметьте, даже не нюанс, а просто известный всем факт... :) так что пока человек научается писать нормально программы на c++ проходит не один год, это в отличие от пресловутых java, python, c# и иже с ними
Ну это то легко лечится shared_ptr-ами, которые однако добавляют оверхеда, особенно в мультитредном окружении. Их вроде бы уже в 0x собираются в std:: включить.
> и это, заметьте, даже не нюанс, а просто известный всем факт... :) так что пока человек научается писать нормально программы на c++ проходит не один год, это в отличие от пресловутых java, python, c# и иже с ними
Ну это то легко лечится shared_ptr-ами, которые однако добавляют оверхеда,
увы, но да - добавляют и добавляют серьёзно, иначе бы не было смысла в boost:scoped_ptr :) но и scoped_ptr тоже добавляет иначе тогда какой смысл использовать обычные указатели :)
в общем см. stl design :)
особенно в мультитредном окружении.
это вообще отдельная большая песня :)
Их вроде бы уже в 0x собираются в std:: включить.
главное чтобы не было как с std::auto_ptr, что вроде и есть, а юзать всё равно стрёмно :)
> Ну это то легко лечится shared_ptr-ами, которые однако добавляют оверхеда, особенно в мультитредном окружении. Их вроде бы уже в 0x собираются в std:: включить.
> увы, но да - добавляют и добавляют серьёзно, иначе бы не было смысла в boost:scoped_ptr :) но и scoped_ptr тоже добавляет иначе тогда какой смысл использовать обычные указатели :)
Вы не правы. Дело как раз в разной семантике указателя
главное чтобы не было как с std::auto_ptr, что вроде и есть, а юзать всё равно стрёмно :)
Ну или может имелось в виду, что выкинут из 0x, как раз заменив на shared_ptr-ы всякие.
Этот факт я из книжки Маерса вычитал, честно говоря в детали не вдавался, т.к. сам auto_ptr-ами не пользуюсь, и никому не разрешаю, кроме случаев, когда он используется исключительно для авторелиза обьекта аллокированного в конкретном scope-е, где гарантированно известно, что указать на обьект никуда никогда не передан будет.
Вообще, да, в реализациях STL-я в том-же gcc auto_ptr пока никуда не делся.
> увы, но да - добавляют и добавляют серьёзно, иначе бы не было смысла в boost:scoped_ptr :) но и scoped_ptr тоже добавляет иначе тогда какой смысл использовать обычные указатели :)
Вы не правы. Дело как раз в разной семантике указателя
простите, но я не очень понял что Вы имеете в виду, поясните пожалуйста
> главное чтобы не было как с std::auto_ptr, что вроде и есть, а юзать всё равно стрёмно :)
ну если компилятор не находит конструктор копии в классе, то он его дописывает туда самостоятельно, но все члены класса копируются простым присваиванием (shallow copy), то есть если у нас есть член класса который является указателем то ему будет присвоен новый адрес и всё... при этом старая область памяти на которую он указывает «утекает», так как на неё уже никто не ссылается, а на область памяти на которую указывала присваиваемая переменная указывают 2 указателя
> Не буду я на работе щас искать, коротко расскажите, плиз
Основной наезд на то, что копирование обьекта модифицирует исходный обьект, и например auto_ptr-ы не затолкать ни в один контейнер, не говоря уже об необходимости очень-очень-очень аккуратно с ними обращаться при копировании обьектов, содержащих auto_ptr-ы мемберами.
Не буду я на работе щас искать, коротко расскажите, плиз
если совсем вкратце то корявая реализация владения указателем (и до истерики смешная при копировании)
в общем смысл фразы такой, что очень часто сам объект диктует семантику владения им
если я Вас правильно понял, то суть проблемы с std::auto_ptr в том что он так распоряжается семантикой владения, что лучше его вообще не использовать :)
а использовать либо std::tr1::shared_ptr и std::tr1::weak_ptr либо boost::shared_ptr и boost::scoped_ptr либо как вариант написать свой smart ptr
Кстати, топикстартер, найди проблему в этом коде, давай, покажи ;) Тут есть один очень коварный косяк, который малозначим в случае показать как работает, а в жизни - опасный.
Я же о другом писал. тут же вызов контсркутора копирования
эммм... напомню о чём речь шла
dialogue
- если компилятор не находит конструктор копии в классе, то он его дописывает туда самостоятельно, но все члены класса копируются простым присваиванием (shallow copy), то есть если у нас есть член класса который является указателем то ему будет присвоен новый адрес и всё... при этом старая область памяти на которую он указывает «утекает», так как на неё уже никто не ссылается, а на область памяти на которую указывала присваиваемая переменная указывают 2 указателя
- А не конструкторы копирования ли он вызывает?
- ога, у char* :)
- Да. Для всех элементарных типов были введены «конструкторы» по умолчанию и «конструкторы копирования» (присвоение нуля и присвание элемент)
так вот конструктор копирования по умолчанию делает тупое побитное копирование и, следовательно, просто копирует адрес из одного указателя в другой
для встроенных типов нет конструкторов копии!
естественно когда он копирует экземпляр класса 1 в экземпляр класса 2 то вызывается конструктор копии экземпляра класса 1 :) но то не про ссылки!