Модераторы: bsa

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> pimpl с применением std::auto_ptr не работает, конструктор пашет, а деструктор нет ;) 
V
    Опции темы
EvilsInterrupt
Дата 24.6.2010, 09:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Executables research
***


Профиль
Группа: Завсегдатай
Сообщений: 1019
Регистрация: 14.7.2007
Где: Железнодорожный, МО, Россия

Репутация: нет
Всего: 9



Для того чтобы пояснить какая у меня в основном проект, я создал поменьше "школьный" вариант.

Файл header1.h содержит:
Код

#ifndef INCLUDE_HEADER1_H
#define INCLUDE_HEADER1_H

#include <memory>

namespace hdr {

  class CMain1 {
  public:
    CMain1();
  private:
    class CPrivate1;
    std::auto_ptr<CPrivate1> m_Private;
  };

} /* namespace hdr { */

#endif /*INCLUDE_HEADER1_H*/


Файл implement1.cpp содержит:
Код

#include "header1.h"
#include <iostream>

#define M_MSG(N, S)  (std::cout << N << " : " << S << std::endl)

namespace hdr {

  class CMain1::CPrivate1 {
  public:
    CPrivate1() : m_val(0)  {
      M_MSG(m_val,"CPrivate1 constructor");
      m_val++;
    }
    ~CPrivate1()  {
      M_MSG(m_val,"CPrivate1 destructor");
      m_val++;
    }
  private:
    int m_val;
  };

  CMain1::CMain1() : m_Private(new CPrivate1)
  {
  }

} /* namespace hdr { */


В результате получаю:
Цитата

1>c:\program files (x86)\microsoft visual studio 9.0\vc\include\memory(718) : warning C4150: deletion of pointer to incomplete type 'hdr::CMain1::CPrivate1'; no destructor called
1>        e:\source\proba\header1.h(13) : see declaration of 'hdr::CMain1::CPrivate1'
1>        c:\program files (x86)\microsoft visual studio 9.0\vc\include\memory(716) : while compiling class template member function 'std::auto_ptr<_Ty>::~auto_ptr(void)'
1>        with


инклуд memory подключен! Самое прикольно создается exe-файл и при отладке отрабатывает конструктор, а деструктор не пашед и я вижу строчку на  экране:

0 : CPrivate1 constructor

т.е. компилятор класс как бы находит, однако почему же он деструктор не осилил ?

подобное можно  найти и тут
PM MAIL WWW ICQ Jabber   Вверх
mes
Дата 24.6.2010, 09:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 79
Всего: 250



auto_ptr должно знать полный класс (определение), а не только его объявление.. 



--------------------
PM MAIL WWW   Вверх
EvilsInterrupt
Дата 24.6.2010, 09:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Executables research
***


Профиль
Группа: Завсегдатай
Сообщений: 1019
Регистрация: 14.7.2007
Где: Железнодорожный, МО, Россия

Репутация: нет
Всего: 9



mes, Ну  как бы директива препроцессора #include вставляет файл и полная единица компиляции. Чего не так-то ? Форвард-декларация должна быть форвардом, а не муляжом!
PM MAIL WWW ICQ Jabber   Вверх
Abyx
Дата 24.6.2010, 09:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 601
Регистрация: 3.11.2009

Репутация: 5
Всего: 10



EvilsInterrupt, прямо скажем ничего она вам не должна.
Есть есть сомнения в ее поведении - почитайте стандарт.
Попробуйте написать тот же код, без include, руками собрав все в 1 файл
PM MAIL   Вверх
mes
Дата 24.6.2010, 09:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 79
Всего: 250



Цитата(EvilsInterrupt @  24.6.2010,  08:07 Найти цитируемый пост)
Форвард-декларация должна быть форвардом, а не муляжом!

так он и есть форвард..  smile

Цитата(EvilsInterrupt @  24.6.2010,  08:03 Найти цитируемый пост)
 deletion of pointer to incomplete type 

сравните ситуации 
Код

class C *c;
delete  c;
class C {
};

Код

class C *c;
class C {
};
delete  c;

smile

Добавлено @ 09:29
Цитата(EvilsInterrupt @  24.6.2010,  08:07 Найти цитируемый пост)
 Ну  как бы директива препроцессора #include

#include тут вообще сбоку..  речь о наличии определения в нужный момент.


Это сообщение отредактировал(а) mes - 24.6.2010, 09:29


--------------------
PM MAIL WWW   Вверх
EvilsInterrupt
Дата 24.6.2010, 09:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Executables research
***


Профиль
Группа: Завсегдатай
Сообщений: 1019
Регистрация: 14.7.2007
Где: Железнодорожный, МО, Россия

Репутация: нет
Всего: 9



>>сравните ситуации
При таких , согласен! ;)

Но, давайте взглянем на std::auto_ptr:
Код

private:
    _Ty *_Myptr;    // the wrapped object pointer
    };

Напишем с указателем в явном виде:
Код

  private:
    class CPrivate1;
    CPrivate1 * m_Private;


Почему-то сейчас уже деструктор находится! А код не изменился,разве что в деструктор ~CMain() добавил удаление m_Private
PM MAIL WWW ICQ Jabber   Вверх
Alexeis
Дата 24.6.2010, 09:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Амеба
Group Icon


Профиль
Группа: Админ
Сообщений: 11743
Регистрация: 12.10.2005
Где: Зеленоград

Репутация: 4
Всего: 459



Цитата(EvilsInterrupt @  24.6.2010,  08:43 Найти цитируемый пост)
Почему-то сейчас уже деструктор находится! А код не изменился,разве что в деструктор ~CMain() добавил удаление m_Private 

  У тебя же реализация в cpp. В этом случае он уже "знает" деструктор.


--------------------
Vit вечная память.

Обсуждение действий администрации форума производятся только в этом форуме

гениальность идеи состоит в том, что ее невозможно придумать
PM ICQ Skype   Вверх
mes
Дата 24.6.2010, 09:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 79
Всего: 250



Цитата(EvilsInterrupt @  24.6.2010,  08:43 Найти цитируемый пост)
Но, давайте взглянем на std::auto_ptr:

ну а теперь подумайте, где в первом примере формируется деструктор у auto_ptr в котором вызыватся delete содержимого.. 
smile

Добавлено @ 09:52
Цитата(EvilsInterrupt @  24.6.2010,  08:43 Найти цитируемый пост)
разве что в деструктор ~CMain() добавил удаление m_Private

во во.. ) а теперь перенесите его внутрь класса  
smile


Это сообщение отредактировал(а) mes - 24.6.2010, 09:52


--------------------
PM MAIL WWW   Вверх
EvilsInterrupt
Дата 24.6.2010, 09:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Executables research
***


Профиль
Группа: Завсегдатай
Сообщений: 1019
Регистрация: 14.7.2007
Где: Железнодорожный, МО, Россия

Репутация: нет
Всего: 9



вроде понял ) Но тогда получается pimpl не возможен на С++ с применением std::auto_ptr .

Просто меня очень бесит,когда инклуд содержит что-то относящееся к информации о реализации. На сях, всегда делал "чистые" инклуды, пользователь библиотеки знал только то что необходимо для использования библиотеки. А тут,  разве что на чистых указателях можно ;)
PM MAIL WWW ICQ Jabber   Вверх
mes
Дата 24.6.2010, 09:59 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 79
Всего: 250



Цитата(EvilsInterrupt @  24.6.2010,  08:56 Найти цитируемый пост)
вроде понял ) Но тогда получается pimpl не возможен на С++ с применением std::auto_ptr .

попробуйте пустой деструктор с определением в cpp добавить... 



--------------------
PM MAIL WWW   Вверх
EvilsInterrupt
Дата 24.6.2010, 10:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Executables research
***


Профиль
Группа: Завсегдатай
Сообщений: 1019
Регистрация: 14.7.2007
Где: Железнодорожный, МО, Россия

Репутация: нет
Всего: 9



mes, пашед! Но тогда где освобождать ресурсы если не  в деструкторе ?
PM MAIL WWW ICQ Jabber   Вверх
mes
Дата 24.6.2010, 10:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 79
Всего: 250



Цитата(EvilsInterrupt @  24.6.2010,  09:12 Найти цитируемый пост)
 Но тогда где освобождать ресурсы если не  в деструкторе ? 

не понял

Добавлено через 2 минуты и 26 секунд
или это Вы про  
Цитата(mes @  24.6.2010,  08:59 Найти цитируемый пост)
пустой деструктор

?
так можете его полным сделать... суть не в этом.. главное чтоб определение деструктура было в точке, в которой все необходимое определено.

Добавлено через 4 минуты и 5 секунд
и еще раз внимательно перечитайте http://forum.vingrad.ru/index.php?showtopi...t&p=2174264
до понимания происходящего.
smile


--------------------
PM MAIL WWW   Вверх
EvilsInterrupt
Дата 24.6.2010, 10:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Executables research
***


Профиль
Группа: Завсегдатай
Сообщений: 1019
Регистрация: 14.7.2007
Где: Железнодорожный, МО, Россия

Репутация: нет
Всего: 9



Я к тому что, если в коде ниже, раскоментить, то ошибка :
Код

    ~CPrivate1()  { /*
      M_MSG(m_val,"CPrivate1 destructor"); 
      m_val++; */
    }

А тело пустым, то все ок! Получается что в конструкторе получил ресурс, а в деструкторе его освобождение не могу прописать ;(


нашел про pimpl в qt
PM MAIL WWW ICQ Jabber   Вверх
mes
Дата 24.6.2010, 10:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 79
Всего: 250



я говорил про деструктор для CMain1.

Добавлено @ 10:30
деструктор Привателя к нашей задаче не относится..

Добавлено @ 10:34
кстати о auto_ptr .. Вы уверены что Вам нужна именно это стратегия хранения ?
так как после этого объект класса, становится не copyable и его нельзя будет добавить например в вектор.


Это сообщение отредактировал(а) mes - 24.6.2010, 10:35


--------------------
PM MAIL WWW   Вверх
EvilsInterrupt
Дата 24.6.2010, 10:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Executables research
***


Профиль
Группа: Завсегдатай
Сообщений: 1019
Регистрация: 14.7.2007
Где: Железнодорожный, МО, Россия

Репутация: нет
Всего: 9



mes, Ну  по теме с конструктором, получил рекомендации создать класс хэндла, который будет создаваться в качестве приватного члена основного класса. Однако я не хочу,эту детализацию выкидывать в хидер, даже в виде декларации класса! Поэтому хочу создать pimpl и уже в файле реализации привести полную декларацию. У меня получается с указателями на форвард класс и дальнейшей его декларацией в файле реализации, но не получается с использованием std::auto_ptr.

>>я говорил про деструктор для CMain1.
сделал. но та же самая ошибка! Да и цель-то, сделать открытие в конструкторе, а освобождение в деструкторе и при этом не вынося декларацию класса CPrivate1 в основной инклуд
PM MAIL WWW ICQ Jabber   Вверх
mes
Дата 24.6.2010, 10:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 79
Всего: 250



Цитата(EvilsInterrupt @  24.6.2010,  09:43 Найти цитируемый пост)
Да и цель-то, сделать открытие в конструкторе, а освобождение в деструкторе и при этом не вынося декларацию класса CPrivate1 в основной инклуд

Покажите что сделали.. а то что то не вяжется smile



--------------------
PM MAIL WWW   Вверх
EvilsInterrupt
Дата 24.6.2010, 11:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Executables research
***


Профиль
Группа: Завсегдатай
Сообщений: 1019
Регистрация: 14.7.2007
Где: Железнодорожный, МО, Россия

Репутация: нет
Всего: 9



>>Покажите что сделали.. а то что то не вяжется
В хидере:
Код

namespace hdr {

  class CMain1 {
  public:
    CMain1();
    ~CMain1() {}
  private:
    std::auto_ptr<class CPrivate1> m_Ptr;
  };

} /* namespace hdr { */


в файле-реализации:
Код

  class CMain1::CPrivate1 {
  public:
    CPrivate1() : m_val(0)  { 
      M_MSG(m_val,"CPrivate1 constructor");
      m_val++;
    }
    ~CPrivate1()  {
      M_MSG(m_val,"CPrivate1 destructor"); 
      m_val++;
    }
  private:
    int m_val;
  };

  CMain1::CMain1() : m_Ptr(new CPrivate1)
  {
  }


В реальном проекте, не  в этом пустышке заместо "m_val(0)" идет открытие OpenSCManagerA, а в деструкторе CloseServiceHandle(m_hSCMngr).
PM MAIL WWW ICQ Jabber   Вверх
mes
Дата 24.6.2010, 11:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 79
Всего: 250



Цитата(mes @  24.6.2010,  08:59 Найти цитируемый пост)
попробуйте пустой деструктор с определением в cpp добавить... 


Цитата(EvilsInterrupt @  24.6.2010,  10:02 Найти цитируемый пост)
  ~CMain1() {}

 smile  smile  smile 

Это сообщение отредактировал(а) mes - 24.6.2010, 11:11


--------------------
PM MAIL WWW   Вверх
EvilsInterrupt
Дата 24.6.2010, 11:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Executables research
***


Профиль
Группа: Завсегдатай
Сообщений: 1019
Регистрация: 14.7.2007
Где: Железнодорожный, МО, Россия

Репутация: нет
Всего: 9



>>~CMain1() {}
почему вызвало удивление ?

Сейчас перенес в реализацию, думал роли не играет, и все ок. но  почему?
PM MAIL WWW ICQ Jabber   Вверх
mes
Дата 24.6.2010, 11:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 79
Всего: 250



Цитата(mes @  24.6.2010,  09:22 Найти цитируемый пост)
и еще раз внимательно перечитайте http://forum.vingrad.ru/index.php?showtopi...t&p=2174264
до понимания происходящего.


P.S. чего то ссылка не работает..
имелся ввиду этот пост :
Цитата

Цитата(EvilsInterrupt)

Но, давайте взглянем на std::auto_ptr:

ну а теперь подумайте, где в первом примере формируется деструктор у auto_ptr в котором вызыватся delete содержимого.. 


Добавлено @ 08:52
Цитата(EvilsInterrupt)

разве что в деструктор ~CMain() добавил удаление m_Private


во во.. ) а теперь перенесите его внутрь класса  



Это сообщение отредактировал(а) mes - 24.6.2010, 11:25


--------------------
PM MAIL WWW   Вверх
baldina
Дата 24.6.2010, 11:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3433
Регистрация: 5.12.2007
Где: Москва

Репутация: 15
Всего: 101



потому что именно в деструкторе ~CMain1() вызывается деструктор auto_ptr и вот в этой точке нужно полное определение CPrivate1, что бы правильно вызвать его деструктор.
т.е. CPrivate1 не надо показывать всем, просто функции, его использующие (в т.ч. ~CMain1()) должны быть в единице компиляции, где он известен
PM MAIL   Вверх
EvilsInterrupt
Дата 24.6.2010, 11:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Executables research
***


Профиль
Группа: Завсегдатай
Сообщений: 1019
Регистрация: 14.7.2007
Где: Железнодорожный, МО, Россия

Репутация: нет
Всего: 9



baldina, Теперь понял, млин,  действительно все логично и никакого колдовства. А я уж было пожалел, что забыл бубен в отчем доме ;)))
PM MAIL WWW ICQ Jabber   Вверх
mes
Дата 24.6.2010, 11:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 79
Всего: 250



baldina, ну вот, не дали человеку немного подумать и самому разобраться smile преподнесли на блюдечке ..
 smile  smile 

Это сообщение отредактировал(а) mes - 24.6.2010, 11:29


--------------------
PM MAIL WWW   Вверх
EvilsInterrupt
Дата 24.6.2010, 11:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Executables research
***


Профиль
Группа: Завсегдатай
Сообщений: 1019
Регистрация: 14.7.2007
Где: Железнодорожный, МО, Россия

Репутация: нет
Всего: 9



mes, ;) Вредный ты ;) Но  спасибо огромное )
PM MAIL WWW ICQ Jabber   Вверх
baldina
Дата 24.6.2010, 11:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3433
Регистрация: 5.12.2007
Где: Москва

Репутация: 15
Всего: 101



mes, ну вопрос то не такой простой, как кажется, когда уже знаешь ответ...
а то еще подумает человек, что в С++ все через ж)))
PM MAIL   Вверх
mes
Дата 24.6.2010, 12:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 79
Всего: 250



Цитата(EvilsInterrupt @  24.6.2010,  10:31 Найти цитируемый пост)
mes, ;) Вредный ты ;)

так я как лучше хотел 
smile
Цитата(baldina @  24.6.2010,  10:59 Найти цитируемый пост)
, ну вопрос то не такой простой, как кажется,

быть может.. мне просто показалось, что на тот момент вся нужная информация, для того чтоб придти к выводам была дана..
оставалось только соединить в целое.. 
smile

Цитата(baldina @  24.6.2010,  10:59 Найти цитируемый пост)
а то еще подумает человек, что в С++ все через ж))) 

ну да, пусть знает, что не всё, однако ..
 smile 



--------------------
PM MAIL WWW   Вверх
Страницы: (2) [Все] 1 2 
Ответ в темуСоздание новой темы Создание опроса
Правила форума "C/C++: Для новичков"
JackYF
bsa

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, JackYF, bsa.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Для новичков | Следующая тема »


 




[ Время генерации скрипта: 0.1172 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.