Samowskaźnik i usuwanie siebie

2008-07-10 17:35

Bez używania mechanizmu odśmiecania istnieje zawsze ryzyko, że skończymy z odwołaniem do obiektu, który został już zniszczony. (Przy używaniu GC też istnieje taka możliwość, ale musielibyśmy niejako sami się postarać, aby wystąpiła). Dlatego zaleca się na przykład, by każdemu wywołaniu delete towarzyszyło zerowanie wskaźnika:

  1. delete p; p = NULL;

dzięki czemu można ochronić się przez problemem wiszących wskaźników (dangling pointers).

Można? No cóż, nie do końca. Istnieje jeszcze możliwość, że obiekt zniszczy się sam, używając po prostu instrukcji delete this (jest to jak najbardziej legalne). A wtedy wszelkie odnoszące się do niego odwołania będą już nieważne.
Chyba że… obiekt sam je wyzeruje. Istnieje mianowicie śmieszny trik, polegający na przekazaniu do niego w konstruktorze wskaźnika na siebie (self-pointer):

  1. Foo* pFoo = new Foo(/* parametry konstruktora */, &pFoo);

A mówiąc dokładniej: wskaźnika na ów wskaźnik (zaczyna się robić ciekawie, prawda? ;]). Musi być on oczywiście zapamiętany, a cała sztuczka polega na tym, że w destruktorze obiektu następuje jego zerowanie:

  1. class Foo
  2. {
  3.     public:
  4.         Foo(/* ... */, Foo** ppSelf = NULL) : m_ppSelf(ppSelf) { /* ... */ }
  5.         ~Foo() { if (ppSelf) *ppSelf = NULL; }
  6.     private:
  7.         Foo* m_ppSelf;
  8. };

I teraz obiekt może radośnie się usuwać kiedy tylko zechce. A tak swoją drogą, jeśli rzeczywiście może on zniknąć w każdej chwili, to może wypadałoby też, aby sprawdzał, czy przypadkiem… już nie istnieje:

  1. void Foo::SomeMethod(/* ... */)
  2. {
  3.     if (!this) return;
  4.     // ...
  5. }

Pokręcone i przekombinowane? Powiedziałbym wręcz, że szalone :) Ale do takich sztuczek trzeba się uciekać, jeśli nie korzystamy z mechanizmów odśmiecania pamięci i nie potrafimy jednoznacznie określić czasu życia obiektów i ich wzajemnej przynależności.
Albo po prostu: gdy nie mamy lepszych pomysłów. Bo przecież w ostateczności lepiej chyba sprawdzi się zwyczajna flaga logiczna z metodą typu IsAlive, jeśli obiekt rzeczywiście może popełnić nagłe samobójstwo. Najlepiej jednak, żeby takich emo-obiektów było jak najmniej ;)

Tags:
Author: Xion, posted under Programming »


2 comments for post “Samowskaźnik i usuwanie siebie”.
  1. agent_J:
    July 11th, 2008 o 11:09

    Czyżbyś musiał użyć CAknNoteDialog (CEikDialog **aSelfPtr, const TTone &aTone=ENoTone, const TTimeout &aTimeout=ENoTimeout) ? ;)

  2. Kos:
    July 21st, 2008 o 16:28

    Pojęcie “emo-obiektu” zasługuje chyba na uwiecznienie. :)

Comments are disabled.
 


© 2019 Karol Kuczmarski "Xion". Layout by Urszulka. Powered by WordPress with QuickLaTeX.com.