| Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
| Форум программистов > C/C++: Общие вопросы > PIMPL+auto_ptr на VS2010 |
| Автор: azesmcar 22.1.2011, 22:44 | ||||||
| Добрый вечер, Есть такая проблема. Реализую PIMPL с использованием умных указателей. Код: x.h
x.cpp
ximpl.h
все нормально, все работает как и положено, но как только я реализую конструктор класса X в заголовочном файле (x.h) VS2010 начинает выдавать warning, что std::auto_ptr мол деструктора не видит (хотя он есть). gcc молчит, все в порядке..опять в микрософт что-то намудрили или так и положено? С решением все просто - отказаться от использования std::auto_ptr и удалять в деструкторе самому, но зачем? |
| Автор: alexvs11 22.1.2011, 22:48 |
| azesmcar, auto_ptr не умный, а очень даже глупый указатель разве shared_ptr не включили в новый стандарт? |
| Автор: azesmcar 22.1.2011, 22:49 |
с каких это пор? в тот, который еще не вышел? |
| Автор: alexvs11 22.1.2011, 23:02 |
| на rsdn'e четко рассказано в чем соль http://www.rsdn.ru/article/cpp/smartptr.xml#EMD в немногих случаях, когда я видел применение auto_ptr это было связано с глюками, которых не было бы без его применения, а в vs для wince я помню он вообще не был полностью реализован а shared_ptr уже в std::tr1, так что скоро будет в стандарте |
| Автор: mes 22.1.2011, 23:02 |
| auto_ptr должен видеть деструктор того класса.. |
| Автор: azesmcar 22.1.2011, 23:04 |
Я знаю, деструктор есть. На работоспособность программы влияет не наличие деструктора, а реализация конструктора в заголовочном файле. Каким образом это связано? auto_ptr должен удаляться в деструкторе класса X, деструктор реализован в cpp файле (x.cpp), где реализация XImpl уже видна. соль чего? auto_ptr? я с ним знаком и он меня более чем устраивает для текущей задачи. скоро, не скоро..не все компиляторы его на сегодняшний день поддерживают. И кстати shared_ptr не замена auto_ptr, они для разных целей служат. |
| Автор: mes 22.1.2011, 23:09 |
нет... деструктор auto_ptr формируется в месте инстантирования тьфу использования.. и там должен быть виден нужный деструктор .. |
| Автор: mes 22.1.2011, 23:17 |
| http://forum.vingrad.ru/forum/topic-304001/unread-1/hl/auto_ptr/index.html |
| Автор: azesmcar 22.1.2011, 23:20 | ||
тут говориться то, о чем пишу я и нет ответа на мой вопрос Добавлено через 22 секунды
|
| Автор: mes 22.1.2011, 23:21 |
| перечитал еще раз.. понял о чем речь.. да я как то криво читал, сорри.. сейчас обдумаю Добавлено через 5 минут и 18 секунд мм.. а деструктор шаблона тоже в хидере ? |
| Автор: azesmcar 22.1.2011, 23:28 | ||||
вот именно что нет, только конструктор..деструктор то я могу перенести в реализацию. Исходник точно такой, как в первом посте (только конструктор шаблонный). Для получения ошибки достаточно заменить в коде из первого поста
на
и убрать реализацию из cpp файла. ну в общем-то как я уже писал решение есть и довольно простое, делать new, delete самому, но хотелось бы разобраться. |
| Автор: mes 23.1.2011, 00:02 |
| полагаю VS формирует _pre-destructor_ там, где формируется конструктор.. |
| Автор: azesmcar 23.1.2011, 07:10 | ||
Это объясняет ошибку, но это странно, что он вызывает деструктор auto_ptr в этом pre деструкторе...а если а в своем деструкторе к нему обращусь? |
| Автор: azesmcar 23.1.2011, 08:28 | ||||||||
| упс...забыл проинициализировать ложная тревога Добавлено @ 08:37
проверил, в деструкторе к impl можно спокойно обращаться, т.е. удаляется объект после выхода из тела деструктора в файле реализации. Почему в таком случае студия хочет деструктора там, где он ей не нужен? в итоге получается вот это. работает, но деструктор XImpl не вызывается. x.h
ximpl.h
x.cpp
|
| Автор: mes 23.1.2011, 12:22 | ||||
ну так и должно оно быть
наверно слово pre_destructor неправильно подобрал.. имелась ввиду такая условная схема:
|
| Автор: azesmcar 23.1.2011, 12:35 | ||
теперь понятнее..и насколько это соответствует стандарту? Добавлено через 20 секунд ну вообще да, так предполагается |
| Автор: mes 23.1.2011, 13:05 |
такая схема или место формирования деструктора ? |
| Автор: azesmcar 23.1.2011, 13:06 |
больше всего интересует итог всего этого, т.е. такое поведение данного кода. |
| Автор: mes 23.1.2011, 14:10 | ||
насчет схемы отсюда можно сделать вывод :
а когда формировать эту часть деструктора, в стандарте вроде не сказано .. |
| Автор: azesmcar 24.1.2011, 06:08 | ||||
ну это естественно.
т.е. именно деструктор должен вызывать, деструкторы для базового классов и членов. тогда это не соответствует стандарту (если это конечно работает именно так) |
| Автор: xvr 24.1.2011, 14:57 | ||
Т.е. то, что она (студия) сгенерила деструктор auto_ptr в конструкторе X::X(), еще не значит, что она его когда либо вообще позовет |
| Автор: mes 24.1.2011, 23:37 | ||
не понял о чем речь.. Добавлено через 1 минуту и 49 секунд да, хороший повод для формирования деструктора.. |
| Автор: azesmcar 25.1.2011, 06:11 | ||||||
Вы описали поведение деструктора вот так
т.е. он формирует пре-деструктор (назовем его так) там, где определен конструктор. По стандарту
т.е. именно деструктор класса X должен вызывать деструкторы своих непосредственных членов, а не пре-деструктор.
ну gcc ведь как-то работает, т.е. задача по сути решаемая. |
| Автор: mes 25.1.2011, 09:41 | ||||||
если по стандарту, то он называется destructor, а то , что определяет пользователь destructor`s body..
ну так разноглассие ввиду неправильно подобранных названий, предыдущий абзац "решает" эту проблему ну а если еще и соответствовать пункту о return, то условно
|
| Автор: xvr 25.1.2011, 11:35 | ||||
Сильно зависит от контекста. Например тут:
А тут:
VS скорее всего не вдается в такие тонкости и просто лепит инстанс деструктора безусловно |
| Автор: azesmcar 25.1.2011, 12:02 | ||||
в gcc нет никаких волнений по этому поводу, все деструкторы нормально вызываются.
в моем примере там вообще ничего нету кроме auto_ptr<XImpl>. На эту тонкость студии тоже по всей видимости плевать
Да, так и есть. Ну в общем уже примерно понятно почему и как..тему закрываю, всем спасибо (хотя дискуссию конечно можно продолжить) |
| Автор: xvr 25.1.2011, 12:31 | ||||||||
А вот если добавить описание класса Y (с деструктором), то его позовут -
|
| Автор: azesmcar 25.1.2011, 12:39 | ||||||||||
| xvr Не совсем понял..можно выложить полный исходники тестового примера? Я только что проверил, все деструкторы вызываются нормально. Добавлено через 7 минут и 21 секунду выкладываю свой пример x.h
ximpl.h
x.cpp
ximpl.cpp
выводит
на gcc version 4.5.1 |
| Автор: xvr 25.1.2011, 12:49 | ||
В примере деструктор Y не вызывается (вне зависимости от исключений и от чего то бы ни было Если раскоментарить тело класса Y в файле 1.cpp, то деструктор вызывается |
| Автор: xvr 25.1.2011, 12:49 |
| Сборка: g++ 1.cpp 2.cpp |
| Автор: azesmcar 25.1.2011, 12:58 | ||
| xvr Это не баг, деструктор в файле 1.cpp явно недоступен, его там просто нет, как и описания всего класса. Ошибка gcc в том, что он не предупредил об этом (странно кстати). Тут кстати SomeClass и не нужен вовсе, он и без этого не будет вызываться. Все дело в том, что у тебя нет деструктора в классе X, а значит он будет сгенерирован компилятором, сгенерирован он будет естестественно в файле 1.cpp, где он никак не может видеть деструктора класса Y и соответственно вызвать его никак не может. Добавлено через 4 минуты и 14 секунд http://www.gotw.ca/publications/mill12.htm
|
| Автор: xvr 25.1.2011, 13:16 | ||||||
PS. Я добавил кое что к примеру, gcc по прежнему вполне счастлив, но результат зависит от порядка линковки файлов:
Вот такие пироги |
| Автор: azesmcar 25.1.2011, 13:18 |
Да, в этом он ошибается Но по части кода ведет он себя как и ожидалось. А вот у меня ситуация немного другая, gcc работает, а VS - нет. Добавлено через 53 секунды вот это уже интереснее |
| Автор: xvr 25.1.2011, 13:37 |
Ну в общем VS прав, но в данном случае он явно 'перебдел' |
| Автор: azesmcar 25.1.2011, 13:39 | ||
Да дело то не в варнинге, деструктор на самом деле не вызывается. |