In c ++ löschen Sie Verweise auf ein Objekt, wenn es gelöscht wird


Derek

Sagen wir A Referenzen B.

Es kann Millionen von B geben, auf die von allen möglichen Dingen verwiesen wird.

Das Problem ist: B kann gelöscht werden und dann könnte A (oder ein anderes Objekt) auf Müll zeigen und wenn es verwendet wird, erhalten wir eine AccessViolation.

Ich denke, die normale Lösung ist, dass B einen Link zurückhalten muss, damit wir die Referenz auf Null setzen können.

Gibt es Arten von intelligenten Zeigern, die sich mit dieser Art von Szenario befassen? zB wenn B gelöscht wird, wird der Verweis auf sich selbst auf Null gesetzt?

Ein Beispiel hinzufügen:

class B
{
  int x;
}

class A
{
   public:
   B* DangerousPointer;
};

Nehmen wir an, B kann jederzeit gelöscht werden, es gibt Millionen von B und viele Dinge, die auf B verweisen können. Ich möchte wissen, ob B gelöscht wurde, damit ich nicht darauf zugreifen und eine Zugriffsverletzung erhalte. Im Idealfall möchte ich nicht, dass B alle A's, die darauf verweisen, im Auge behalten muss, damit A den Zeiger auf B auf Null setzen kann, wenn B gelöscht wird.

Eine weitere Frage zur Verwendung von schwachem_ptr:

Unsere Software verwendet derzeit überhaupt kein schwaches_ptr oder gemeinsames_ptr. Wir haben eine smurfClass (Schlumpf-Namenskonvention), die eine Liste von smurfAttributes enthält.

Wenn eine smurfClass gelöscht wird, löschen wir auch alle smurfAttributes. Viele andere Dinge möchten möglicherweise auf ein smurfAttribute verweisen, aber gelegentlich treten Probleme auf, wenn wir eine Klasse und alle ihre Attribute löschen und etwas auf ein gelöschtes smurfAttribute verweist.

Ist es möglich, ein schwaches_ptr an ein smurfAttribute zu verteilen?

Aus den Dokumenten geht hervor:

Die Klassenvorlage "soft_ptr" speichert einen "schwachen Verweis" auf ein Objekt, das bereits von einem shared_ptr verwaltet wird.

Bedeutet dies, dass ich ein schwaches_ptr nicht einfach an ein smurfAttribute weitergeben kann (da es nicht von einem shared_ptr verwaltet wird)? Ich möchte das smurfAttribute nicht am Leben erhalten, aber ich muss wissen, ob es gelöscht wurde, damit ich es nicht verwenden kann.

NathanOliver

Dafür ist a da std::shared_ptr. Wenn Sie eine erstellen, shared_ptrsolange eine Referenz vorhanden ist, ist der Speicher weiterhin gültig. Hier ist ein kleines Beispiel für die Verwendung eines gemeinsam genutzten Zeigers:

#include <iostream>
#include <memory>

void use_shared_ptr(std::shared_ptr<int> sp)
{
    std::cout << "in use_shared_ptr() count is: " << sp.use_count() << std::endl;
}

std::shared_ptr<int> function_that_returns_a_local_object()
{
    auto foo = std::make_shared<int>(42);
    std::cout << "just created shared_ptr.  count is: " << foo.use_count() << std::endl;
    use_shared_ptr(foo);
    std::cout << "after use_shared_ptr(foo) count is " << foo.use_count() << std::endl;
    return foo;
} // oh no.  foo gets destroyed here.  what is going to happen?

int main() 
{
    auto bar = function_that_returns_a_local_object();
    std::cout << "back in main count is: " << bar.use_count() << std::endl;
}

Ausgabe:

just created shared_ptr.  count is: 1
in use_shared_ptr() count is: 2
after use_shared_ptr(foo) count is 1
back in main count is: 1

Das Plus daran ist, dass es keine manuelle Speicherverwaltung gibt und wenn es dann vollständig fertig ist shared_ptr, zerstört es sich selbst und bereinigt den Speicher, der ihm zugewiesen wurdemake_shared

Sie könnten auch eine std::weak_ptr. A weak_ptrermöglicht das Löschen des zugrunde liegenden Zeigers, es sei denn, Sie rufen auf lock, wodurch ein gemeinsamer Zeiger erstellt wird, der die Lebensdauer des zugrunde liegenden Zeigers verlängert, bis der Zeiger shared_ptrgelöscht wird. Sie würden dies normalerweise verwenden, wenn Sie dem Anrufer ein Objekt geben möchten, aber Sie möchten ihm keine Garantie geben, dass es noch am Leben ist, wenn er es verwenden möchte. weak_ptrEs gibt eine Möglichkeit zu überprüfen, ob der zugrunde liegende Zeiger gelöscht wurde, und es kann auch in einen konvertiert werden, shared_ptrwenn die Objekte vorhanden sind, sodass Sie die Lebensdauer des Zeigers verlängern können, während Sie ihn verwenden.

BEARBEITEN:

Als Antwort auf die Hinzufügung zu Ihrer Frage würden smurfClassalle in der smurfAttributesals gespeichert std::shared_ptr<smurfAttributes>. Dann würden Sie in der Funktion, die das Attribut an andere weitergibt, a zurückgeben std::weak_ptr. Auf diese Weise muss der Empfänger des Attributs versuchen, das Attribut zu sperren, weak_ptrum es verwenden zu können. Wenn dies nicht möglich ist, weiß er, dass es kein gültiges Attribut mehr hat.

Verwandte Artikel