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

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> PIMPL+auto_ptr на VS2010, проблема реализации 
V
    Опции темы
azesmcar
Дата 22.1.2011, 22:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


uploading...
****


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

Репутация: 81
Всего: 211



Добрый вечер,

Есть такая проблема. Реализую PIMPL с использованием умных указателей.
Код:
x.h
Код

#ifndef x_h_included
#define x_h_included

#include <memory>

class XImpl;
class X
{
public:
    X();
    ~X();
    std::auto_ptr<XImpl> impl;
};

#endif // x_h_included

x.cpp
Код

#include "ximpl.h"
#include "x.h"

X::X()
{
}

X::~X()
{

}

ximpl.h
Код

#ifndef ximpl_h_included
#define ximpl_h_included

class XImpl
{
public:
    XImpl() {};
    ~XImpl() {};
};

#endif // ximpl_h_included

все нормально, все работает как и положено, но как только я реализую конструктор класса X в заголовочном файле (x.h) VS2010 начинает выдавать warning, что std::auto_ptr мол деструктора не видит (хотя он есть). gcc молчит, все в порядке..опять в микрософт что-то намудрили или так и положено? С решением все просто - отказаться от использования std::auto_ptr и удалять в деструкторе самому, но зачем?

Это сообщение отредактировал(а) azesmcar - 22.1.2011, 22:46
PM   Вверх
alexvs11
Дата 22.1.2011, 22:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


hell is here
**


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

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



azesmcar, auto_ptr не умный, а очень даже глупый указатель
разве shared_ptr не включили в новый стандарт?
PM MAIL   Вверх
azesmcar
Дата 22.1.2011, 22:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


uploading...
****


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

Репутация: 81
Всего: 211



Цитата(alexvs11 @  22.1.2011,  22:48 Найти цитируемый пост)
azesmcar, auto_ptr не умный, а очень даже глупый указатель

с каких это пор?

Цитата(alexvs11 @  22.1.2011,  22:48 Найти цитируемый пост)
разве shared_ptr не включили в новый стандарт? 

в тот, который еще не вышел?

PM   Вверх
alexvs11
Дата 22.1.2011, 23:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


hell is here
**


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

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



на rsdn'e четко рассказано в чем соль
http://www.rsdn.ru/article/cpp/smartptr.xml#EMD
в немногих случаях, когда я видел применение auto_ptr это было связано с глюками, которых не было бы без его применения, а в vs для wince я помню он вообще не был полностью реализован  smile 
а shared_ptr уже в std::tr1, так что скоро будет в стандарте

Это сообщение отредактировал(а) alexvs11 - 22.1.2011, 23:04
PM MAIL   Вверх
mes
Дата 22.1.2011, 23:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


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


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

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



auto_ptr должен видеть деструктор того класса..


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


uploading...
****


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

Репутация: 81
Всего: 211



Цитата(mes @  22.1.2011,  23:02 Найти цитируемый пост)
auto_ptr должен видеть деструктор того класса.. 

Я знаю, деструктор есть. На работоспособность программы влияет не наличие деструктора, а реализация конструктора в заголовочном файле. Каким образом это связано? auto_ptr должен удаляться в деструкторе класса X, деструктор реализован в cpp файле (x.cpp), где реализация XImpl уже видна.

Цитата(alexvs11 @  22.1.2011,  23:02 Найти цитируемый пост)
на rsdn'e четко рассказано в чем соль

соль чего? auto_ptr? я с ним знаком и он меня более чем устраивает для текущей задачи.

Цитата(alexvs11 @  22.1.2011,  23:02 Найти цитируемый пост)
а shared_ptr уже в std::tr1, так что скоро будет в стандарте

скоро, не скоро..не все компиляторы его на сегодняшний день поддерживают. И кстати shared_ptr не замена auto_ptr, они для разных целей служат.

Это сообщение отредактировал(а) azesmcar - 22.1.2011, 23:09
PM   Вверх
mes
Дата 22.1.2011, 23:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


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


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

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



Цитата(azesmcar @  22.1.2011,  22:04 Найти цитируемый пост)
auto_ptr должен удаляться в деструкторе класса X, 

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


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


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


uploading...
****


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

Репутация: 81
Всего: 211



Цитата(mes @  22.1.2011,  23:09 Найти цитируемый пост)
нет... деструктор auto_ptr формируется в месте инстанцирования.. и там должен быть виден нужный деструктор ..

формируется - да, но не вызывается.
а вызывается он уже там, где реализация видна.

код в первом посте нормально компилируется и работает, вопрос в том, что он перестает работать (точнее просто выдает warning) как только я пишу конструктор в заголовочном файле. А я не могу его писать в файле реализации, он шаблонный.

Добавлено через 5 минут и 16 секунд
Цитата(alexvs11 @  22.1.2011,  23:02 Найти цитируемый пост)
в немногих случаях, когда я видел применение auto_ptr это было связано с глюками, которых не было бы без его применения

и о чем это говорит?

Добавлено через 6 минут и 23 секунды
mes

http://www.gotw.ca/publications/mill12.htm
Цитата

A General Technique: Using the Pimpl Idiom

  //  Example 2: The general solution to
  //             Cargill's Widget Example
  //
  class Widget
  {
    // ...

  private:
    class WidgetImpl;
    auto_ptr<WidgetImpl> pimpl_;

    // ... provide destruction, copy construction
    //     and assignment that work correctly, or
    //     suppress them ...
  };

  // Then, typically in a separate
  // implementation file:
  //
  class Widget::WidgetImpl
  {
  public:
    // ...
    T1 t1_;
    T2 t2_;
  };


Это сообщение отредактировал(а) azesmcar - 22.1.2011, 23:15
PM   Вверх
mes
Дата 22.1.2011, 23:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


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


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

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





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


uploading...
****


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

Репутация: 81
Всего: 211



Цитата(mes @  22.1.2011,  23:17 Найти цитируемый пост)
http://forum.vingrad.ru/forum/topic-304001..._ptr/index.html 

тут говориться то, о чем пишу я и нет ответа на мой вопрос smile

Добавлено через 22 секунды
Цитата(baldina @  24.6.2010,  11:21 Найти цитируемый пост)
потому что именно в деструкторе ~CMain1() вызывается деструктор auto_ptr и вот в этой точке нужно полное определение CPrivate1, что бы правильно вызвать его деструктор.
т.е. CPrivate1 не надо показывать всем, просто функции, его использующие (в т.ч. ~CMain1()) должны быть в единице компиляции, где он известен 


PM   Вверх
mes
Дата 22.1.2011, 23:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


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


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

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



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

Добавлено через 5 минут и 18 секунд
Цитата(azesmcar @  22.1.2011,  22:10 Найти цитируемый пост)
. А я не могу его писать в файле реализации, он шаблонный.

мм.. а деструктор шаблона тоже в хидере ?
 


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


uploading...
****


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

Репутация: 81
Всего: 211



Цитата(mes @  22.1.2011,  23:21 Найти цитируемый пост)
мм.. а деструктор шаблона тоже в хидере ?

вот именно что нет, только конструктор..деструктор то я могу перенести в реализацию. Исходник точно такой, как в первом посте (только конструктор шаблонный). Для получения ошибки достаточно заменить в коде из первого поста
Цитата

X();

на
Код

X() {}

и убрать реализацию из cpp файла.

ну в общем-то как я уже писал решение есть и довольно простое, делать new, delete самому, но  хотелось бы разобраться.


Это сообщение отредактировал(а) azesmcar - 22.1.2011, 23:30
PM   Вверх
mes
Дата 23.1.2011, 00:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


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


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

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



полагаю VS формирует _pre-destructor_ там, где формируется конструктор..


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


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


uploading...
****


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

Репутация: 81
Всего: 211



Цитата(mes @  23.1.2011,  00:02 Найти цитируемый пост)
полагаю VS формирует _pre-destructor_ там, где формируется конструктор..

Это объясняет ошибку, но это странно, что он вызывает деструктор auto_ptr в этом pre деструкторе...а если а в своем деструкторе к нему обращусь?
PM   Вверх
azesmcar
Дата 23.1.2011, 08:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


uploading...
****


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

Репутация: 81
Всего: 211



упс...забыл проинициализировать smile 

ложная тревога

Добавлено @ 08:37
Цитата(mes @  23.1.2011,  00:02 Найти цитируемый пост)
полагаю VS формирует _pre-destructor_ там, где формируется конструктор..

проверил, в деструкторе к impl можно спокойно обращаться, т.е. удаляется объект после выхода из тела деструктора в файле реализации. Почему в таком случае студия хочет деструктора там, где он ей не нужен?

в итоге получается вот это.
работает, но деструктор XImpl не вызывается. smile 

x.h
Код

#ifndef x_h_included
#define x_h_included

#include <memory>

class XImpl;
class X
{
public:
    X()
    {
        init();
    }
    ~X();
private:
    void init();
    std::auto_ptr<XImpl> impl;
};

#endif // x_h_included

ximpl.h
Код

#ifndef ximpl_h_included
#define ximpl_h_included

class XImpl
{
public:
    XImpl() {};
    ~XImpl() {};
    void foo() {}
};

#endif // ximpl_h_included

x.cpp
Код

#include "ximpl.h"
#include "x.h"

X::~X()
{
    impl->foo();
}

void X::init()
{
    impl.reset(new XImpl());
}



Это сообщение отредактировал(а) azesmcar - 23.1.2011, 08:44
PM   Вверх
mes
Дата 23.1.2011, 12:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


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


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

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



Цитата(azesmcar @  23.1.2011,  07:28 Найти цитируемый пост)
проверил, в деструкторе к impl можно спокойно обращаться, т

ну так и должно оно быть smile


Цитата(azesmcar @  23.1.2011,  07:28 Найти цитируемый пост)
Почему в таком случае студия хочет деструктора там, где он ей не нужен?

наверно слово pre_destructor неправильно подобрал.. 
имелась ввиду такая условная схема:
Код

A::~A() 
${  
      {  ...  } // определенный пользователем деструктор
... // вызов деструкторов  дата-членов и базовых
$} 




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


uploading...
****


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

Репутация: 81
Всего: 211



Цитата(mes @  23.1.2011,  12:22 Найти цитируемый пост)
наверно слово pre_destructor неправильно подобрал.. 
имелась ввиду такая условная схема:

теперь понятнее..и насколько это соответствует стандарту? smile

Добавлено через 20 секунд
Цитата(mes @  23.1.2011,  12:22 Найти цитируемый пост)
ну так и должно оно быть 

ну вообще да, так предполагается smile 
PM   Вверх
mes
Дата 23.1.2011, 13:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


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


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

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



Цитата(azesmcar @  23.1.2011,  11:35 Найти цитируемый пост)
и насколько это соответствует стандарту? 

такая схема или место формирования деструктора ?



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


uploading...
****


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

Репутация: 81
Всего: 211



Цитата(mes @  23.1.2011,  13:05 Найти цитируемый пост)
такая схема или место формирования деструктора ?

больше всего интересует итог всего этого, т.е. такое поведение данного кода.
PM   Вверх
mes
Дата 23.1.2011, 14:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


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


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

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



насчет схемы отсюда можно сделать вывод :
Цитата

After executing the body of the destructor and destroying any automatic objects allocated within the body, a destructor for class X calls the destructors for X’s direct members, the destructors for X’s direct base classes ...
...
A return statement (6.6.3) in a destructor might not directly return to the caller; before transferring control to the caller, the destructors for
the members and bases are called.

а когда формировать эту часть деструктора, в стандарте вроде не сказано .. 



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


uploading...
****


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

Репутация: 81
Всего: 211



Цитата(mes @  23.1.2011,  14:10 Найти цитируемый пост)
A return statement (6.6.3) in a destructor might not directly return to the caller; before transferring control to the caller, the destructors for
the members and bases are called.

ну это естественно.

Цитата(mes @  23.1.2011,  14:10 Найти цитируемый пост)
After executing the body of the destructor and destroying any automatic objects allocated within the body, a destructor for class X calls the destructors for X’s direct members, the destructors for X’s direct base classes ...

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

Цитата(mes @  23.1.2011,  12:22 Найти цитируемый пост)
// вызов деструкторов  дата-членов и базовых

тогда это не соответствует стандарту (если это конечно работает именно так)
PM   Вверх
xvr
Дата 24.1.2011, 14:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

Репутация: 60
Всего: 223



Цитата(azesmcar @  23.1.2011,  08:28 Найти цитируемый пост)
проверил, в деструкторе к impl можно спокойно обращаться, т.е. удаляется объект после выхода из тела деструктора в файле реализации. Почему в таком случае студия хочет деструктора там, где он ей не нужен?
Возможно он ей нужен, что бы сгенерить код поддержки исключений, для раскрутки стека в возможном исключении после вызова конструктора std::auto_ptr<XImpl> (хотя его там и нет smile )
Т.е. то, что она (студия) сгенерила деструктор auto_ptr в конструкторе X::X(), еще не значит, что она его когда либо вообще позовет  smile 



Это сообщение отредактировал(а) xvr - 24.1.2011, 14:58
PM MAIL   Вверх
mes
Дата 24.1.2011, 23:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


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


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

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



Цитата(azesmcar @  24.1.2011,  05:08 Найти цитируемый пост)
тогда это не соответствует стандарту (если это конечно работает именно так) 

не понял о чем речь..

Добавлено через 1 минуту и 49 секунд
Цитата(xvr @  24.1.2011,  13:57 Найти цитируемый пост)
Возможно он ей нужен, что бы сгенерить код поддержки исключений,

да, хороший повод для формирования деструктора..


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


uploading...
****


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

Репутация: 81
Всего: 211



Цитата(mes @  24.1.2011,  23:37 Найти цитируемый пост)
не понял о чем речь..

Вы описали поведение деструктора вот так

Цитата(mes @  23.1.2011,  12:22 Найти цитируемый пост)
A::~A() 
${  
      {  ...  } // определенный пользователем деструктор
... // вызов деструкторов  дата-членов и базовых
$} 

т.е. он формирует пре-деструктор (назовем его так) там, где определен конструктор. По стандарту
Цитата

a destructor for class X calls the destructors for X’s direct members

т.е. именно деструктор класса X должен вызывать деструкторы своих непосредственных членов, а не пре-деструктор.

Цитата(xvr @  24.1.2011,  14:57 Найти цитируемый пост)
Возможно он ей нужен, что бы сгенерить код поддержки исключений, для раскрутки стека в возможном исключении после вызова конструктора std::auto_ptr<XImpl> (хотя его там и нет  )
Т.е. то, что она (студия) сгенерила деструктор auto_ptr в конструкторе X::X(), еще не значит, что она его когда либо вообще позовет   

ну gcc ведь как-то работает, т.е. задача по сути решаемая. smile 
PM   Вверх
mes
Дата 25.1.2011, 09:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


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


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

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



Цитата(azesmcar @  25.1.2011,  05:11 Найти цитируемый пост)
т.е. он формирует пре-деструктор (назовем его так) там, где определен конструктор. По стандарту

если по стандарту, то он называется destructor, а то , что определяет пользователь destructor`s body..

Цитата(azesmcar @  25.1.2011,  05:11 Найти цитируемый пост)
т.е. именно деструктор класса X должен вызывать деструкторы своих непосредственных членов, а не пре-деструктор.

ну так разноглассие ввиду неправильно подобранных названий, предыдущий абзац "решает" эту проблему  smile 

ну а если еще и соответствовать пункту о return, то условно 
Код

A::A ()          __DTOR(A, 
{
    //  user defined
} 
)
//  при
#define __DTOR(cls,user_code) 
{
    struct l {
         static body    (cls this)  user_code
         static destroy (cls this) { ... }
    }
    l::body ();
    l::destroy();
}






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


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

Репутация: 60
Всего: 223



Цитата(azesmcar @  25.1.2011,  06:11 Найти цитируемый пост)
ну gcc ведь как-то работает, т.е. задача по сути решаемая.

Сильно зависит от контекста. Например тут:
Код

class X {
 std::auto_ptr<Y> some;
 SomeClass obj_with_nontrivial_constructor;
public:
 X(Y* y) :some(y) {}
};
деструктор для Y реально понадобится, т.к. порядок конструирования членов - some а затем obj_with_nontrivial_constructor, и в случае исключения в конструкторе obj_with_nontrivial_constructor придется звать деструктор для Y.
А тут:
Код

class X {
 SomeClass obj_with_nontrivial_constructor;
 std::auto_ptr<Y> some;
public:
 X(Y* y) :some(y) {}
};
деструктор для Y не нужен, т.к. порядок конструирования членов обратный, и после конструктора auto_ptr исключение возникнуть не может (т.к. просто негде).  smile 

VS скорее всего не вдается в такие тонкости и просто лепит инстанс деструктора безусловно  smile 

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


uploading...
****


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

Репутация: 81
Всего: 211



Цитата(xvr @  25.1.2011,  11:35 Найти цитируемый пост)
Сильно зависит от контекста. Например тут:

в gcc нет никаких волнений по этому поводу, все деструкторы нормально вызываются.

Цитата(xvr @  25.1.2011,  11:35 Найти цитируемый пост)
деструктор для Y реально понадобится, т.к. порядок конструирования членов - some а затем obj_with_nontrivial_constructor, и в случае исключения в конструкторе obj_with_nontrivial_constructor придется звать деструктор для Y.

в моем примере там вообще ничего нету кроме auto_ptr<XImpl>. На эту тонкость студии тоже по всей видимости плевать smile 

Цитата(xvr @  25.1.2011,  11:35 Найти цитируемый пост)
VS скорее всего не вдается в такие тонкости и просто лепит инстанс деструктора безусловно   

Да, так и есть. smile 

Ну в общем уже примерно понятно почему и как..тему закрываю, всем спасибо (хотя дискуссию конечно можно продолжить) smile 

Это сообщение отредактировал(а) azesmcar - 25.1.2011, 12:05
PM   Вверх
xvr
Дата 25.1.2011, 12:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

Репутация: 60
Всего: 223



Цитата(azesmcar @  25.1.2011,  12:02 Найти цитируемый пост)
в gcc нет никаких волнений по этому поводу, все деструкторы нормально вызываются.
Увы, не нормально. Сделал тестовый пример:
Код

#include <memory>

class SomeClass {
public:
 SomeClass();
 ~SomeClass();
};

class Y;

class X {
 std::auto_ptr<Y> some;
 SomeClass obj_with_nontrivial_constructor;
public:
 X(Y* y) :some(y) {}
};

void q(Y* y)
{
 new X(y);
}
gcc 4.5.1. Деструктор для std::auto_ptr<Y> был сгенерен, но деструктора для Y в нем не позвали :(

Код

std::auto_ptr<Y>::~auto_ptr():
    .cfi_startproc
    pushq    %rbp
    .cfi_def_cfa_offset 16
    movq    %rsp, %rbp
    .cfi_offset 6, -16
    .cfi_def_cfa_register 6
    subq    $16, %rsp
    movq    %rdi, -8(%rbp)
    movq    -8(%rbp), %rax
    movq    (%rax), %rax
    movq    %rax, %rdi
    call    operator delete(void*)
    leave
    .cfi_def_cfa 7, 8
    ret
    .cfi_endproc


А вот если добавить описание класса Y (с деструктором), то его позовут -
Код

std::auto_ptr<Y>::~auto_ptr():
    .cfi_startproc
    pushq    %rbp
    .cfi_def_cfa_offset 16
    movq    %rsp, %rbp
    .cfi_offset 6, -16
    .cfi_def_cfa_register 6
    pushq    %rbx
    subq    $24, %rsp
    movq    %rdi, -24(%rbp)
    movq    -24(%rbp), %rax
    movq    (%rax), %rbx
    .cfi_offset 3, -24
    testq    %rbx, %rbx
    je    .L10
    movq    %rbx, %rdi
    call    Y::~Y()
    movq    %rbx, %rdi
    call    operator delete(void*)
.L10:
    addq    $24, %rsp
    popq    %rbx
    leave
    .cfi_def_cfa 7, 8
    ret
    .cfi_endproc
Так что это явно баг в gcc  smile 

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


uploading...
****


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

Репутация: 81
Всего: 211



xvr

Не совсем понял..можно выложить полный исходники тестового примера? Я только что проверил, все деструкторы вызываются нормально.

Добавлено через 7 минут и 21 секунду
выкладываю свой пример

x.h
Код

#ifndef x_h_included
#define x_h_included

#include <memory>
#include <map>

class XImpl;
class X
{
    std::map<int, int> obj_with_nontrivial_constructor;
    std::auto_ptr<XImpl> impl;
private:
    void create_ximpl();
public:
    X()
    {
        this->create_ximpl();
    };
    ~X();
};

#endif // x_h_included


ximpl.h
Код

#ifndef ximpl_h_included
#define ximpl_h_included

#include <iostream>

class XImpl
{
public:
    XImpl();
    ~XImpl();
};
#endif // ximpl_h_included

x.cpp
Код

#include <iostream>
#include "ximpl.h"
#include "x.h"

void X::create_ximpl()
{
    impl.reset(new XImpl());
}

X::~X()
{
    std::cout << "X::~X()" << std::endl;
}

int main()
{
    X x;
}

ximpl.cpp
Код

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

XImpl::XImpl()
{
    std::cout << "XImpl::XImpl()" << std::endl;
}
XImpl::~XImpl()
{
    std::cout << "XImpl::~XImpl()" << std::endl;
};


выводит
Цитата

X::~X()
XImpl::~XImpl()

на gcc version 4.5.1
PM   Вверх
xvr
Дата 25.1.2011, 12:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

Репутация: 60
Всего: 223



Цитата(azesmcar @  25.1.2011,  12:39 Найти цитируемый пост)
Не совсем понял..можно выложить полный исходники тестового примера?

В примере деструктор Y не вызывается (вне зависимости от исключений и от чего то бы ни было  smile  )
Если раскоментарить тело класса Y в файле 1.cpp, то деструктор вызывается


Присоединённый файл ( Кол-во скачиваний: 4 )
Присоединённый файл  bug.zip 0,73 Kb
PM MAIL   Вверх
xvr
Дата 25.1.2011, 12:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

Репутация: 60
Всего: 223



Сборка: g++ 1.cpp 2.cpp

Это сообщение отредактировал(а) xvr - 25.1.2011, 12:50
PM MAIL   Вверх
azesmcar
Дата 25.1.2011, 12:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


uploading...
****


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

Репутация: 81
Всего: 211



xvr

Это не баг, деструктор в файле 1.cpp явно недоступен, его там просто нет, как и описания всего класса. Ошибка gcc в том, что он не предупредил об этом (странно кстати). Тут кстати SomeClass и не нужен вовсе, он и без этого не будет вызываться. Все дело в том, что у тебя нет деструктора в классе X, а значит он будет сгенерирован компилятором, сгенерирован он будет естестественно в файле 1.cpp, где он никак не может видеть деструктора класса Y и соответственно вызвать его никак не может.

Добавлено через 4 минуты и 14 секунд
http://www.gotw.ca/publications/mill12.htm
Цитата

Aside: Note that if you use an auto_ptr member, then: a) you must either provide the definition of WidgetImpl with the definition of Widget, or if you want to keep hiding WidgetImpl you must write your own destructor for Widget even if it's a trivial destructor;[2] and b) you should also provide your own copy construction and assignment for Widget because normally you don't want transfer-of-ownership semantics for class members. If you have a different kind of smart pointer available, consider using that instead of auto_ptr, but the principles being described here remain important.


Это сообщение отредактировал(а) azesmcar - 25.1.2011, 13:01
PM   Вверх
xvr
Дата 25.1.2011, 13:16 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

Репутация: 60
Всего: 223



Цитата(azesmcar @  25.1.2011,  12:58 Найти цитируемый пост)
Ошибка gcc в том, что он не предупредил об этом (странно кстати).
Именно! В этом и ошибка, VS кстати предупреждает.

Цитата(azesmcar @  25.1.2011,  12:58 Найти цитируемый пост)
Тут кстати SomeClass и не нужен вовсе, он и без этого не будет вызываться.
Угу, это остаток от эксперимента с эксепшенами.

PS. Я добавил кое что к примеру, gcc по прежнему вполне счастлив, но результат зависит от порядка линковки файлов:
Код

[rakhvato@msteplxl41 qq1]$ g++ 2.cpp 1.cpp                                              
[rakhvato@msteplxl41 qq1]$ ./a.out 
~X()
~Y()
[rakhvato@msteplxl41 qq1]$  g++ 1.cpp 2.cpp                                              
[rakhvato@msteplxl41 qq1]$ ./a.out 
~X()

Вот такие пироги  smile 


Присоединённый файл ( Кол-во скачиваний: 2 )
Присоединённый файл  bug.zip 0,84 Kb
PM MAIL   Вверх
azesmcar
Дата 25.1.2011, 13:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


uploading...
****


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

Репутация: 81
Всего: 211



Цитата(xvr @  25.1.2011,  13:16 Найти цитируемый пост)
Именно! В этом и ошибка, VS кстати предупреждает.

Да, в этом он ошибается smile 
Но по части кода ведет он себя как и ожидалось. А вот у меня ситуация немного другая, gcc работает, а VS - нет. smile

Добавлено через 53 секунды
Цитата(xvr @  25.1.2011,  13:16 Найти цитируемый пост)
Вот такие пироги   

вот это уже интереснее smile  smile 
PM   Вверх
xvr
Дата 25.1.2011, 13:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

Репутация: 60
Всего: 223



Цитата(azesmcar @  25.1.2011,  13:18 Найти цитируемый пост)
А вот у меня ситуация немного другая, gcc работает, а VS - нет.

Ну в общем VS прав, но в данном случае он явно 'перебдел'  smile Так что можно отключить в этом месте этот варнинг и жить спокойно  smile 

PM MAIL   Вверх
azesmcar
Дата 25.1.2011, 13:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


uploading...
****


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

Репутация: 81
Всего: 211



Цитата(xvr @  25.1.2011,  13:37 Найти цитируемый пост)
Ну в общем VS прав, но в данном случае он явно 'перебдел'   Так что можно отключить в этом месте этот варнинг и жить спокойно   

Да дело то не в варнинге, деструктор на самом деле не вызывается. smile 
PM   Вверх
Страницы: (3) [Все] 1 2 3 
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
Earnest Daevaorn

Добро пожаловать!

  • Черновик стандарта C++ (за октябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика(4.4мб).
  • Черновик стандарта C (за сентябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика (3.4мб).
  • Прежде чем задать вопрос, прочтите это и/или это!
  • Здесь хранится весь мировой запас ссылок на документы, связанные с C++ :)
  • Не брезгуйте пользоваться тегами [code=cpp][/code].
  • Пожалуйста, не просите написать за вас программы в этом разделе - для этого существует "Центр Помощи".
  • C++ FAQ

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

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


 




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


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

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