[Socketd <db@traceroute.dk> wrote:]
>Når du nu opretter et objekt på heap'en (med new) og dette objekt kan
>blive medlem af flere container klasser, hvordan er det så smartest at
>behandle sletning af dette objekt?
Meget meget forsigtigt!
Først skal du gøre det klart for dig selv, om du vil (1) lave en "slet
mig" funktion på objektet, som så skal sørge for at "informere"
container klasserne at "nu sletter jeg mig selv", og afvente at alle
container klasserne har ryddet objektet fra deres lister, førend
objektet kan slette sig selv.
Eller (2) en "udestående" funktion, som får besked på at "slet dette
objekt", og skal derefter sørge for at kalde alle container klasserne
med "fjern dette objekt fra din liste hvis du har det", for til sidst at
slette objektet.
Forresten er det (almindelig) C++, eller det nyere C# du bruger? Jeg går
ud fra at det er C++.
BTW: Hvis du ikke kender "C++ FAQ Lite" så får du den lige her;
"
http://www.parashift.com/c++-faq-lite/". Den er rigtig god at kikke i,
og lære nogle "interessante" kode konstruktioner.
>Du kan jo selvfølgelig forsøge at huske at kalde, noget ala removeXXX,
>ved alle de forskellige Cklasser, men vil det være meget fyfy at lave en
>vector i klassen/objektet som indeholder function-pointers til de
>removeXXX funktioner i alle container klasser, hvor opjektet befinder
>sig?
Det vil være meget omstændigt. Lad os sige at der er 10
container-objekter og eet data-objekt, som er blevet "meldt ind" i de 10
container-objekter. Så skal dette ene data-objekt altså bruge 10x
hukommelse for at vide at den er i 10 forskellige container-objekter.
Gang nu ovenstående med 1000 data-objekter eller mere... ;-/
Og om tre måneder laver du en ny container-klasse, så skal du også ind
og ændre data-klassen.
>Så behøver du jo ikke fra container klassens siden være bange for
>at delete et objekt, der allerede er deleted eller bruge et ojbekt, der
>ikke findes længere?
Her bør du bruge "Reference counting". Altså i stedet for at
data-objektet har pointere tilbage til container-objekterne som den
"tror" den er i, så har den i stedet en "reference tæller" som beskriver
i hvor mange container-objekter som data-objektet er refereret fra.
Bemærk at reference tælleren _ikke_ beskriver i _hvilke_
container-objekter referencen er! Læs forslag (2) igen.
Søg på Google efter "C++ Reference Counting" (og lignende søge navne)
for at få mere litteratur/eksempler.
Hvis man bruger "Reference counting", så bør man også skjule (beskytte)
destructor (som minimum) og evt. constructor på disse klasser, således
at man sikrer at reference tælling mod data-objektet altid foretages
igennem kontrollerede funktioner. Følgende er noget her-og-nu tastet
pseudo-kode (som tilfældigvis ligner meget C++, men jeg sikrer mig lige
mod syntax-fejl og ting som ikke kan lade sig gøre i C++.)
class MyReferencedClass
{
public:
static MyReferencedClass* Create();
static void Destroy(MyReferencedClass*);
MyReferencedClass* Referenced();
int GetReferenceCount() { return m_ReferenceCount; }
protected:
MyReferencedClass() {};
~MyReferencedClass() {};
// Man må ikke destructe objektet, før reference-
// count er nul! Derfor bør destructor være beskyttet.
private:
int m_ReferenceCount;
};
MyReferencedClass* MyReferencedClass::Create()
{
MyReferencedClass *object = new MyReferencedClass();
object->m_ReferenceCount = 1;
return object;
}
MyReferencedClass* MyReferencedClass::Referenced()
{
++m_ReferenceCount;
return this;
}
void MyReferencedClass::Destroy(MyReferencedClass *obj)
{
//! @todo Test for negative reference-count, which is bad.
if (0 == --m_ReferenceCount)
{
// Only physically delete object, when reference-count
// has reached zero.
delete obj;
}
}
int main(int argc, char *argv[])
{
//MyReferencedClass *obj1 = new MyReferencedClass;
//<- Compiler error. Constructor is protected.
MyReferencedClass *obj1 = MyReferencedClass::Create();
MyReferencedClass *obj1_igen = obj1->Referenced();
//delete obj1; //<- Compiler error. Destructor is protected.
cout << obj1_igen->GetReferenceCount() << endl;
obj1->Destroy();
obj1 = NULL;
cout << obj1_igen->GetReferenceCount() << endl;
obj1_igen->Destroy();
obj1_igen = NULL;
}
--
/Decker -
http://www.planetquake.com/quark - map-editor for Half-Life & more.
q1r3p3x7re_qx@ubgznvy.pbz. E-mail spam-guard: I'm no '1337', so remove/rot13.