Konstrukt zwei Shared_ptr Objekte aus dem gleichen Zeiger
-
22-08-2019 - |
Frage
Ich habe ein Problem von "The C ++ Standard Library Extensions":
Übung 6
Ich sagte in Abschnitt 2.4.2 dass Sie sollten nicht zwei konstruieren Shared_ptr Objekte aus dem gleichen Zeiger. Die Gefahr besteht darin, dass sowohl Shared_ptr Objekte oder deren Nachkommen wird schließlich versuchen, das löschen Ressource, und das führt in der Regel zu Ärger. In der Tat können Sie dies tun, wenn Sie sind vorsichtig. Es ist nicht besonders nützlich, schreiben, aber ein Programm, das Konstrukte zwei Shared_ptr Objekte aus der gleiche Zeiger und löscht die Ressource nur einmal.
unten ist meine Antwort:
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;
}
, aber ich glaube nicht, es ist eine gute Lösung - weil ich will es nicht durch die Verwendung Konstruktor lösen. kann mir jemand einen besseren geben? thx, verzeih mein schlechtes Englisch.
Lösung 4
Ich habe die "STANDARD" Antwort von boost doc: http: // www.boost.org/doc/libs/1%5F38%5F0/libs/smart%5Fptr/sp%5Ftechniques.html#another_sp
Andere Tipps
Alles, was Sie tun müssen, ist den zweiten shared_ptr
vom ersten shared_ptr
zu konstruieren.
shared_ptr<SX> sp1( new SX );
shared_ptr<SX> sp2( sp1 );
Die erstellte SX wird dann richtig nur gelöscht werden, wenn alle freigegebenen Zeiger auf sie zerstört werden.
Der Trick gefunden Sie ist gültig, wenn auch unnütz. Das zentrale Merkmal von shared_ptr
ist Referenzzählung, die Sie hier unterminieren. Die deleter (die zweite Konstruktorargument) ist es für mit anderen Ressourcen dann Ebene unter Verwendung von Zeigern shared_ptr
. Man könnte es mit Dateien verwenden, z:
typedef boost::shared_ptr FilePtr;
void FileClose( FILE* pf ) { if ( pf ) fclose( pf ); }
FilePtr pfile( fopen( "filename" ), FileClose );
Das Gleiche gilt für Datenbankverbindungen, Steckdosen, etc. etc. und RAII im Allgemeinen.
Sie können sehen, wie boost löst es mit shared_from_this . Hier ist der Code rel="nofollow.