cnheying
cnheying

Reputation: 91

construct two shared_ptr objects from the same pointer

I have a problem from "The C++ Standard Library Extensions":

Exercise 6
I said in Section 2.4.2 that you shouldn't construct two shared_ptr objects from the same pointer. The danger is that both shared_ptr objects or their progeny will eventually try to delete the resource, and that usually leads to trouble. In fact, you can do this if you're careful. It's not particularly useful, but write a program that constructs two shared_ptr objects from the same pointer and deletes the resource only once.

below is my answer:

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;
}

but I don't think it is a good solution--because i don't want solving it by use constructor. can anyone give me a better one? thx, forgive my bad english.

Upvotes: 4

Views: 2060

Answers (4)

cnheying
cnheying

Reputation: 91

I got the "STANDARD" answer from boost doc : http://www.boost.org/doc/libs/1%5F38%5F0/libs/smart%5Fptr/sp%5Ftechniques.html#another_sp

Upvotes: 0

Drew Dormann
Drew Dormann

Reputation: 63839

All you need to do is construct the second shared_ptr from the first shared_ptr.

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

The created SX will then properly be deleted only when all shared pointers to it are destroyed.

Upvotes: 3

Nikolai Fetissov
Nikolai Fetissov

Reputation: 84189

The trick you found is valid, though useless. The central feature of shared_ptr is reference-counting, which you subvert here. The deleter (the second constructor argument) is there for using shared_ptr with resources other then plain pointers. You could use it with files, e.g:


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

Same with database connections, sockets, etc. etc. and RAII in general.

Upvotes: 2

i_am_jorf
i_am_jorf

Reputation: 54610

You can look at how boost solves it with shared_from_this. Here's the code.

Upvotes: 1

Related Questions