2013-10-02 8 views
8

Ich möchte rohe Zeiger Mitglied zu einigen Smart-Pointer Wrapping Wrapping innerhalb einer Entwicklungsklasse zu verhindern. Besitzer des Objekts unter Zeiger befindet sich außerhalb der Klasse. Also, sieht aus wie boost::shared_ptr und std::auto_ptr passt nicht. Das folgende ist ein reduziertes Beispiel:Erstellen von weak_ptr <> aus rohen Zeiger

class Foo { 
    boost::weak_ptr<Bar> m_bar; 
public: 
    void setBar(const Bar *bar) { // bar created on heap 
    m_bar = bar;    // naturally compilation error 
    } 
}; 

Natürlich induziert es Kompilierungsfehler. Was ist eine korrekte Methode, um weak_ptr von einem rohen Zeiger zu initialisieren (falls vorhanden)?

+0

möglich Duplikat [shared \ _ptr & schwachen \ _ptr tun Konvertierungen] (http://stackoverflow.com/questions/17522020/shared-ptr-weak-ptr-conversions) –

+1

Wenn Sie das Löschen dieses Zeigers in Ihrer Klasse verhindern wollen, dann rufen Sie 'delete' nicht darauf auf und stellen Sie keine Accessor-Funktionen bereit, die den Zeiger den Clients verfügbar machen. 'weak_ptr' ist für die nicht-besitzende Ansicht eines Objekts gedacht, das einem' shared_ptr' gehört. Wenn Sie in der Lage wären, diesen Zeiger in ein "weak_ptr" zu stopfen, hätte er keine Ahnung, ob der Zeiger abgelaufen ist, noch hindert er mich daran, 'delete m_bar.lock(). Get(); 'in Ihrer Klasse aufzurufen. Du kannst niemals alles 100% idiotensicher machen. – Praetorian

Antwort

10

Sie können das nicht tun, können Sie nur eine weak_ptr aus einem shared_ptr oder anderen weak_ptr erstellen. Also die Idee wäre, dass der Besitzer des Zeigers ein shared_ptr anstelle eines rohen Zeigers hält, und alles sollte in Ordnung sein.

1

Übergeben Sie den freigegebenen Zeiger anstelle des unverarbeiteten Zeigers, und erstellen Sie Ihren schwachen Zeiger aus diesem freigegebenen Zeiger. Dies ist die einzige Möglichkeit, wenn der Besitzer des Zeigers außerhalb einer Klasse ist.

4

Der Zweck eines schwachen Zeiger nicht in der Lage sein, den rohen Zeiger zu verwenden, wenn sie gelöscht worden war. Wenn Sie jedoch einen rohen Zeiger haben, kann der schwache Zeiger nicht wissen, dass er gelöscht wurde. Stattdessen müssen Sie eine shared_ptr irgendwo haben, die den rohen Zeiger "besitzt". Dann können Sie ein weak_ptr erstellen, das auf shared_ptr verweist.

Wenn shared_ptr den Gültigkeitsbereich verlässt und der letzte "starke" intelligente Zeiger ist, wird der rohe Zeiger automatisch gelöscht. Wenn Sie dann versuchen, den weak_ptr zu sperren, wird es sehen, dass kein "starker" Zeiger übrig ist und daher das Objekt nicht existiert.

2

Alles, was Sie gesagt haben, scheint durchaus sinnvoll, mit einer Ausnahme:

void setBar(const Bar *bar) 

Dies sollte keinen Rohzeiger nehmen. Es sollte ein weak_ptr idealerweise oder möglicherweise ein shared_ptr nehmen, wenn Sie zwingendes Argument haben.

Der tatsächliche Besitzer des betreffenden Objekts sollte das weak_ptr konstruieren und dann setBar damit aufrufen. Dies bewahrt die Besitz-Semantik. Es sieht so aus, als würden Sie das besitzende Objekt mit einem rohen Zeiger versehen und an setBar übergeben. Dies erzeugt eine semantische Lücke im Besitz des Objekts.

5

Der einzige Weg, es zu tun ist, indem Sie sich ein shared_ptr oder weak_ptr erhalten, die den Zeiger besitzt, da sonst die weak_ptr keine Möglichkeit hat, die bestehenden Eigentümer zu teilen, um das Eigentum mit ihm zu finden.

Der einzige Weg, um ein shared_ptr aus einem rohen Zeiger zu erhalten, die bereits von einer anderen shared_ptr Besitz ist, wenn Bar von enable_shared_from_this<Bar> leitet, dann können Sie

m_bar = bar->shared_from_this(); 
Verwandte Themen