Построить два объекта shared_ptr из одного и того же указателя

У меня есть проблема из "Стандартных расширений библиотеки C++":

Упражнение 6
В разделе 2.4.2 я сказал, что не следует создавать два объекта shared_ptr из одного и того же указателя. Опасность заключается в том, что оба объекта shared_ptr или их потомство в конечном итоге попытаются удалить ресурс, что обычно приводит к проблемам. На самом деле, вы можете сделать это, если вы осторожны. Это не особенно полезно, но напишите программу, которая создает два объекта shared_ptr из одного и того же указателя и удаляет ресурс только один раз.

ниже мой ответ:

template <typename T>
void nonsence(T*){}
struct SX {
     int data;
     SX(int i = 0) :
              data(i) {
              cout << "SX" << endl;
     }
     ~SX() {
              cout << "~SX" << endl;
     }
};
int main(int argc, char **argv) {
    SX* psx=new SX;
    shared_ptr<SX> sp1(psx),sp2(psx,nonsence<SX>);
    cout<<sp1.use_count()<<endl;
    return 0;
}

но я не думаю, что это хорошее решение - потому что я не хочу решать его с помощью конструктора использования. кто-нибудь может дать мне лучший? THX, прости мой плохой английский.

4 ответа

Решение

Я получил ответ "СТАНДАРТ" от boost doc: http://www.boost.org/doc/libs/1_38_0/libs/smart_ptr/sp_techniques.html

Все, что вам нужно сделать, это построить второй shared_ptr от первой shared_ptr,

shared_ptr<SX> sp1( new SX );
shared_ptr<SX> sp2( sp1 );

Созданный SX будет затем правильно удален, только когда все общие указатели на него будут уничтожены.

Трюк, который вы нашли, действителен, но бесполезен. Центральная особенность shared_ptr это подсчет ссылок, который вы подрываете здесь. Удалитель (второй аргумент конструктора) предназначен для использования shared_ptr с ресурсами, отличными от простых указателей. Вы можете использовать его с файлами, например:


typedef boost::shared_ptr FilePtr;
void FileClose( FILE* pf ) { if ( pf ) fclose( pf ); }
FilePtr pfile( fopen( "filename" ), FileClose );

То же самое с соединениями с базой данных, сокетами и т. Д. И т. Д. И RAII в целом.

Вы можете посмотреть, как boost решает проблему с помощью shared_from_this. Вот код

Другие вопросы по тегам