| Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
| Форум программистов > C/C++: Для новичков > pimpl с применением std::auto_ptr не работает |
| Автор: EvilsInterrupt 24.6.2010, 09:03 | ||||||
| Для того чтобы пояснить какая у меня в основном проект, я создал поменьше "школьный" вариант. Файл header1.h содержит:
Файл implement1.cpp содержит:
В результате получаю:
инклуд memory подключен! Самое прикольно создается exe-файл и при отладке отрабатывает конструктор, а деструктор не пашед и я вижу строчку на экране: 0 : CPrivate1 constructor т.е. компилятор класс как бы находит, однако почему же он деструктор не осилил ? подобное можно найти и http://www.insidecpp.ru/patterns/pimpl_idiom |
| Автор: mes 24.6.2010, 09:06 |
| auto_ptr должно знать полный класс (определение), а не только его объявление.. |
| Автор: EvilsInterrupt 24.6.2010, 09:07 |
| mes, Ну как бы директива препроцессора #include вставляет файл и полная единица компиляции. Чего не так-то ? Форвард-декларация должна быть форвардом, а не муляжом! |
| Автор: Abyx 24.6.2010, 09:13 |
| EvilsInterrupt, прямо скажем ничего она вам не должна. Есть есть сомнения в ее поведении - почитайте стандарт. Попробуйте написать тот же код, без include, руками собрав все в 1 файл |
| Автор: mes 24.6.2010, 09:27 | ||||
так он и есть форвард.. сравните ситуации
Добавлено @ 09:29 #include тут вообще сбоку.. речь о наличии определения в нужный момент. |
| Автор: EvilsInterrupt 24.6.2010, 09:43 | ||||
| >>сравните ситуации При таких , согласен! ;) Но, давайте взглянем на std::auto_ptr:
Напишем с указателем в явном виде:
Почему-то сейчас уже деструктор находится! А код не изменился,разве что в деструктор ~CMain() добавил удаление m_Private |
| Автор: mes 24.6.2010, 09:49 | ||
ну а теперь подумайте, где в первом примере формируется деструктор у auto_ptr в котором вызыватся delete содержимого.. Добавлено @ 09:52
во во.. ) а теперь перенесите его внутрь класса |
| Автор: EvilsInterrupt 24.6.2010, 09:56 |
| вроде понял ) Но тогда получается pimpl не возможен на С++ с применением std::auto_ptr . Просто меня очень бесит,когда инклуд содержит что-то относящееся к информации о реализации. На сях, всегда делал "чистые" инклуды, пользователь библиотеки знал только то что необходимо для использования библиотеки. А тут, разве что на чистых указателях можно ;) |
| Автор: mes 24.6.2010, 09:59 | ||
попробуйте пустой деструктор с определением в cpp добавить... |
| Автор: EvilsInterrupt 24.6.2010, 10:12 |
| mes, пашед! Но тогда где освобождать ресурсы если не в деструкторе ? |
| Автор: mes 24.6.2010, 10:22 |
не понял Добавлено через 2 минуты и 26 секунд или это Вы про ? так можете его полным сделать... суть не в этом.. главное чтоб определение деструктура было в точке, в которой все необходимое определено. Добавлено через 4 минуты и 5 секунд и еще раз внимательно перечитайте http://forum.vingrad.ru/index.php?showtopic=304001&view=findpost&p=2174264 до понимания происходящего. |
| Автор: EvilsInterrupt 24.6.2010, 10:26 | ||
Я к тому что, если в коде ниже, раскоментить, то ошибка :
А тело пустым, то все ок! Получается что в конструкторе получил ресурс, а в деструкторе его освобождение не могу прописать ;( нашел про pimpl в http://habrahabr.ru/blogs/qt_software/76248/ |
| Автор: mes 24.6.2010, 10:29 |
| я говорил про деструктор для CMain1. Добавлено @ 10:30 деструктор Привателя к нашей задаче не относится.. Добавлено @ 10:34 кстати о auto_ptr .. Вы уверены что Вам нужна именно это стратегия хранения ? так как после этого объект класса, становится не copyable и его нельзя будет добавить например в вектор. |
| Автор: EvilsInterrupt 24.6.2010, 10:43 |
| mes, Ну по теме с конструктором, получил рекомендации создать класс хэндла, который будет создаваться в качестве приватного члена основного класса. Однако я не хочу,эту детализацию выкидывать в хидер, даже в виде декларации класса! Поэтому хочу создать pimpl и уже в файле реализации привести полную декларацию. У меня получается с указателями на форвард класс и дальнейшей его декларацией в файле реализации, но не получается с использованием std::auto_ptr. >>я говорил про деструктор для CMain1. сделал. но та же самая ошибка! Да и цель-то, сделать открытие в конструкторе, а освобождение в деструкторе и при этом не вынося декларацию класса CPrivate1 в основной инклуд |
| Автор: mes 24.6.2010, 10:46 | ||
Покажите что сделали.. а то что то не вяжется |
| Автор: EvilsInterrupt 24.6.2010, 11:02 | ||||
| >>Покажите что сделали.. а то что то не вяжется В хидере:
в файле-реализации:
В реальном проекте, не в этом пустышке заместо "m_val(0)" идет открытие OpenSCManagerA, а в деструкторе CloseServiceHandle(m_hSCMngr). |
| Автор: mes 24.6.2010, 11:10 |
| Автор: EvilsInterrupt 24.6.2010, 11:15 |
| >>~CMain1() {} почему вызвало удивление ? Сейчас перенес в реализацию, думал роли не играет, и все ок. но почему? |
| Автор: mes 24.6.2010, 11:19 | ||||||||
P.S. чего то ссылка не работает.. имелся ввиду этот пост :
|
| Автор: baldina 24.6.2010, 11:21 |
| потому что именно в деструкторе ~CMain1() вызывается деструктор auto_ptr и вот в этой точке нужно полное определение CPrivate1, что бы правильно вызвать его деструктор. т.е. CPrivate1 не надо показывать всем, просто функции, его использующие (в т.ч. ~CMain1()) должны быть в единице компиляции, где он известен |
| Автор: EvilsInterrupt 24.6.2010, 11:24 |
| baldina, Теперь понял, млин, действительно все логично и никакого колдовства. А я уж было пожалел, что забыл бубен в отчем доме ;))) |
| Автор: mes 24.6.2010, 11:29 |
| baldina, ну вот, не дали человеку немного подумать и самому разобраться |
| Автор: EvilsInterrupt 24.6.2010, 11:31 |
| mes, ;) Вредный ты ;) Но спасибо огромное ) |
| Автор: baldina 24.6.2010, 11:59 |
| mes, ну вопрос то не такой простой, как кажется, когда уже знаешь ответ... а то еще подумает человек, что в С++ все через ж))) |
| Автор: mes 24.6.2010, 12:26 |
так я как лучше хотел быть может.. мне просто показалось, что на тот момент вся нужная информация, для того чтоб придти к выводам была дана.. оставалось только соединить в целое.. ну да, пусть знает, что не всё, однако .. |