Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Общие вопросы > auto_ptr & PIMPL idiom


Автор: IKM2007 8.7.2012, 11:24
Доброго дня. Допустим есть следующие классы

SimpleClass.h
Код


#include <iostream>
class SimpleClass
{
public:
    SimpleClass()
    {
        std::cout<<"constructor\n";
    }
    ~SimpleClass()
    {
        std::cout<<"destructor\n";
    }
};


ClassOwner.h
Код

#include <memory>
class ClassOwner 
{ 
public:  
ClassOwner(); 
private: 
class SimpleClass;
std::auto_ptr<SimpleClass> m_impl;
};


ClassOwner.cpp
Код

#include "ClassOwner.h" 
#include "SimpleClass.h" 
ClassOwner::
ClassOwner():  m_impl(new SimpleClass) { }


тогда при выполнении следующего кода


main.cpp
Код

#include "ClassOwner.h" 
int main() 
{ 
ClassOwner o; 
return 0; 
}


получим вывод:
constructor

Как я понимаю дело происходит так? Компилятор смотрит на обьявление класса ClassOwner, видит что там нету деструктора и генерирует свой деструктор по умолчанию. В генерированном деструкторе он "должен" вызвать деструкторы всех членов класса, то есть в нашем случае деструктор auto_ptr<SimpleClass>. НО он пока что не знает что из себя представляет SimpleClass, следовательно не может даже вызвать деструктор auto_ptr, следовательно не будет вызван также деструктор SimpleClass-а? Или он все таки в силах конструировать деструктор auto_ptr, но во время delete-а в деструкторе auto_ptr не может найти destructor для неполного типа? Какой из этих вариантов правильный? Или же все совсем иначе?

Автор: mes 8.7.2012, 11:34
IKM2007, 
при использовании авто_птр в овнере нужно определить (пустой) деструктор, там где есть уже полное описание импла.. и еще о копи-конструкторе следует позаботиться..

Добавлено через 3 минуты и 2 секунды
Цитата(IKM2007 @  8.7.2012,  10:24 Найти цитируемый пост)
 Или он все таки в силах конструировать деструктор auto_ptr, но во время delete-а в деструкторе auto_ptr не может найти destructor для неполного типа? Какой из этих вариантов правильный? 

да, это проблема не самого ауто_птр, а делете для неполного типа.. 

Автор: IKM2007 8.7.2012, 11:38
Цитата(mes @  8.7.2012,  11:34 Найти цитируемый пост)
при использовании авто_птр в овнере нужно определить (пустой) деструктор, там где есть уже полное описание импла.. и еще о копи-конструкторе следует позаботиться..

Чтобы компилятор не создал свой деструктор ДО просмотра реализации этого класса, следовательно до полного определения impl-а?

И все таки
Цитата(IKM2007 @  8.7.2012,  11:24 Найти цитируемый пост)
он пока что не знает что из себя представляет SimpleClass, следовательно не может даже вызвать деструктор auto_ptr, следовательно не будет вызван также деструктор SimpleClass-а? Или он все таки в силах конструировать деструктор auto_ptr, но во время delete-а в деструкторе auto_ptr не может найти destructor для неполного типа? Какой из этих вариантов правильный?


Добавлено через 6 минут и 3 секунды
Цитата(mes @  8.7.2012,  11:34 Найти цитируемый пост)
и еще о копи-конструкторе следует позаботиться..

А если не определить копи-конструктор, он в сгенерированном даст ошибку или не сделает ничего?

Автор: mes 8.7.2012, 11:50
Цитата(IKM2007 @  8.7.2012,  10:38 Найти цитируемый пост)
А если не определить копи-конструктор, он в сгенерированном даст ошибку или не сделает ничего? 

ну так у ауто_птр есть же копи-конструктор.....

Добавлено через 1 минуту и 20 секунд
Цитата(IKM2007 @  8.7.2012,  10:38 Найти цитируемый пост)
Чтобы компилятор не создал свой деструктор ДО просмотра реализации этого класса, следовательно до полного определения impl-а?

ага, с целью чтоб делете деструктора ауто_птр знала о импле..

Автор: IKM2007 8.7.2012, 12:08
Цитата(mes @  8.7.2012,  11:50 Найти цитируемый пост)
ну так у ауто_птр есть же копи-конструктор.....

Да

Код

auto_ptr (auto_ptr& rhs) throw() 
        : ap(rhs.release()) {
      }

tempiate<class Y>
      auto_ptr (auto_ptr<Y>& rhs) throw() 
        : ap(rhs.release()) { }


Тогда все должно быть нормально, так как он просто передаст указатель на обьект новому auto_ptr.

Добавлено через 48 секунд
Тогда зачем нам переопределить копи-конструктор?

Автор: mes 8.7.2012, 12:18
Цитата(IKM2007 @  8.7.2012,  11:08 Найти цитируемый пост)

Тогда зачем нам переопределить копи-конструктор? 

потому что семантика копирования ауто_птр отличается от той, которая требуется в большинстве случаев и является ожидаемой.. 

Цитата(IKM2007 @  8.7.2012,  11:08 Найти цитируемый пост)
тогда все должно быть нормально, так как он просто передаст указатель на обьект новому auto_ptr.

а что будет со старым ? как его использовать ?

Автор: IKM2007 8.7.2012, 12:37
Цитата(mes @  8.7.2012,  12:18 Найти цитируемый пост)
потому что семантика копирования ауто_птр отличается от токой которая требуется в большинстве случаев и является ожидаемой.. 

Ладно понял. Спасибо! smile 

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)