Generischer Zugriff auf Destruktor



  • Hallo zusammen,

    Im Folgenden geht es um eine gerichtete Assoziation zwischen zwei Klassen. ClassA zeigt auf ClassB.
    Die Beziehung soll später zur Laufzeit gesetzt werden können. Das klappt soweit über die entsprechende Methode. Wenn nun ein Objekt auf das vorher gezeigt wurde gelöscht wird, soll über den Destruktor der Pointer der zeigenden Klasse, wieder auf NULL gesetzt werden. Hier komme ich nicht weiter. Anbei der Code:

    #include <iostream>
    
    using namespace std;
    
    class ClassB
    {
    friend class ClassA;
    
    public:
    
        ClassB();
        ~ClassB();
    
    };
    
    ClassB::ClassB()
    {
        cout << "ClassB erstellt" << endl;
    }
    
    ClassB::~ClassB()
    
    {
        cout << "ClassB geloescht" << endl;
    }
    
    class ClassA
    {
    
    private:
        ClassB *assoziationsZeiger = NULL; // ein Zeiger auf ClassB
    public:
        ClassA();
        ~ClassA();
    
        void assoziationSetzen(ClassB &a);
    
    };
    
    void ClassA::assoziationSetzen(ClassB &a)
    {
        cout << "Adresse von ObjektDerKlasseB: " << assoziationsZeiger << endl;
        this->assoziationsZeiger = &a;
        cout << "Adresse des ObjektDerKlasseB: " << assoziationsZeiger << endl;
    }
    
    ClassA::ClassA()
    {
        cout << "ClassA erstellt" << endl;
    }
    
    ClassA::~ClassA()
    
    {
        cout << "ClassA geloescht" << endl;
    }
    
    int main()
    {
        ClassA ObjektDerKlasseA;
        ClassB ObjektDerKlasseB;
        ObjektDerKlasseA.assoziationSetzen(ObjektDerKlasseB);
    
        return 0;
    }
    

    Über friend Klassen und Methoden bin ich nicht weitergekommen.
    Ein Versuch war über eine Methode der classA den Destruktor von classB aufzurufen.

    Grüße



  • B muß halt auch A kennen. Dann kann ein sterbendes B das zugehörige A informieren.



  • Ja das ist richtig, die Assoziation soll aber unidirektional bleiben.


  • Mod

    Destruktoren rufst du bitte niemals manuell auf. Wenn du irgendwann einmal C++-Experte bist, kannst du dir seltene Ausnahmefälle überlegen, in denen das angebracht sein könnte.

    Das auslösende Ereignis ist die Zerstörung des B-Objekts, die Musik spielt also im B-Destruktor. Dazu muss das B-Objekt auf irgendeine Art und Weise wissen, welches oder welche A-Objekte es ändern soll. Das heißt, irgendwo muss registriert sein, welche A-Objekte auf ein bestimmtes B-Objekt zeigen. Dies kann an verschiedenen Stellen erfolgen, welche genau die beste ist, kommt drauf an, wie das Verhältnis von A und B genau ist. An diesem abstrakten Beispiel kann man es nicht sicher sagen. Eine Idee wäre, dass ein B-Objekt alle A-Objekte kennt, die auf es zeigen. Eine andere Idee wäre eine zentrale Verwaltungsstelle, an der registriert ist, wer auf wen zeigt, die das B-Objekt bei Bedarf fragen kann.

    PS: In C++ nimmt man nullptr, NULL ist C.



  • Erst mal besten Dank für die Ratschläge. Das ist natürlich naheliegend, dass B-Objekte am besten die entsprechenden A-Objekte kennen. Aber dann ist die Assoziation doch bidirektional geworden - oder?



  • Eine andere Möglichkeit ist, dass ausschließlich ein Objekt von ClassA sein Objekt von ClassB im assoziationsZeiger aus dem Speicher entfernen darf. Damit brauchen wie gewünscht, Objekte von ClassB keine Ahnung von referenzierenden Objekten haben. Dafür würde ich dann sicherheitshalber den dtor von ClassB schützen (ClassA ist ja schon friend).


Log in to reply