2012-11-13 10 views
6

Ich bin nicht sicher, ob ich mehr von einem Dokumentationsfehler oder Kopfschmerzen leiden, so ...Wie kann ich ein shared_ptr zu einem Mitglied erstellen?

Was ich will ist zu tun, um eine shared_ptr zu schaffen, dass mit einem anderen Aktie Eigentum, das aber verweist auf ein Mitglied das Objekt anstelle des gesamten Objekts. Einfaches Beispiel, Ausgangspunkt ...

struct s 
{ 
    int a, b; 
}; 

shared_ptr<s> s1 (new s); // pointing to whole object 

Von en.cppreference.com, Konstruktor (8) von shared_ptr ist ...

template< class Y > 
shared_ptr(const shared_ptr<Y>& r, T *ptr); 

Die Beschreibung erwähnt „ein shared_ptr Konstrukte, die Eigentümerinformationen mit r teilt, aber enthält einen nicht verwandten und nicht verwalteten Zeiger ptr ... wie in den typischen Anwendungsfällen, in denen ptr ein Mitglied des von r verwalteten Objekts ist.

Also ... Wurde T gerade versehentlich von der Vorlage in diesem Konstruktor verpasst, oder fehle ich etwas? In der Tat sieht Y aus, als wäre es auch falsch für mich, also wird der Konstruktor in der Regel korrekt beschrieben?

Was ich hoffe, dass ich tun kann, so etwas wie dieses ...

shared_ptr<int> s2 (s1, &(s1.get()->a)); 

s2 Punkte Mitglied a (ein int), aber Aktien Besitz des gesamten Objekts mit s1.

Ist das gesund?

+0

Vielleicht bin ich etwas fehlt, aber warum sollte man eine shared_ptr an ein Mitglied var möchten, die nicht zugeordnet auf dem Haufen? also warum nicht einfach einen rohen Zeiger für s2 benutzen? –

+0

@RC - um sicherzustellen, dass, wenn die ursprüngliche shared_ptr freigegeben wird, das Objekt selbst nicht - dh um sicherzustellen, dass s2 nicht zu einem dangling Zeiger wird. In einem realen Beispiel sind die Bereiche von s1 und s2 nicht identisch. – Steve314

+0

Ja, es ist vollkommen gesund. Sie brauchen auch kein '.get()'. – atzz

Antwort

9

T Der Parameter sind ein Template-Parameter auf den shared_ptr selbst, während die Y Parameter ein Template-Parameter auf diesem bestimmten shared_ptr Konstruktor ist. Etwas wie das:

Wie für den Beispielcode, den Sie gepostet haben, sieht das gut für mich aus.

+0

Jeder hat Recht - Sie gewinnen, um ein bisschen schneller zu sein. Ich fühle mich ein bisschen dumm - ich habe in letzter Zeit offensichtlich nicht viel Template-Zeug gemacht. Ich habe Member-Templates komplett vergessen. – Steve314

4

Die Dokumentation ist korrekt. Sie vergessen, dass dies die Dokumentation eines Konstruktor auf der Klassenvorlage ist shared_ptr<T> das heißt, die Klasse qualifizierte Erklärung des Konstrukteurs ist:

template<typename T> 
template<typename Y> 
shared_ptr<T>::shared_ptr(const shared_ptr<Y>& r, T *ptr); 

So in Ihrem Beispiel T ist int und Y ist s.

2

T ist der Vorlagenparameter der Klasse, nicht des Konstruktors. Und das ist genau so, wie es sein muss: Ein Zeiger auf ein Mitglied muss den Typ des Mitglieds haben und vergessen/löschen (siehe Typ-Löschen) den Typ des enthaltenden Objekts (in diesem Fall Y).

Der Code, den Sie geschrieben funktionieren sollte, können Sie es sogar ein wenig einfacher schreiben als:

shared_ptr<int> s2 (s1, &s1->a); 
+0

Aus irgendeinem Grund bin ich nie sicher über den Vorrang von '&' - wahrscheinlich, weil ich immer zusätzliche Parens hinzufügen, anstatt zu überprüfen. Das "Get" war ebenfalls beabsichtigt, aber ich bin mir nicht sicher, ob das Machen-der-Dinge-expliziteres Denken sinnvoll ist. Ich sollte wirklich dabei bleiben, meine Kopfschmerzen zu beschuldigen. – Steve314

Verwandte Themen