Objektreferenzierung



  • Hallo,

    ich habe ein Objektmodell mit vier Objekten (A, B, C, D). A->B und B->C sowie B->D.

    Nun soll B->A oder auch D->B auch möglich sein. B enthält dazu eine Methode, die einen Shared Pointer auf A zurückgibt.

    Wie realisiere ich das Modell am Besten? Boost und C++11 stehen zur Verfügung.

    Es dürfen natürlich keine Zyklen auftreten, sonst wird der Speicher bei Shared Pointern nicht freigegeben. 🙂



  • Was bedeutet A->B? Vererbung? Komposition?



  • haha, geht sowas eig?
    A erbt von B, B erbt von A?
    noch nie ausprobiert xD

    @TE: wenn es komposition ist, dann speicher dir in den besitzenden objekten einen shared_ptr und in den davon abhängigen objekten jeweils einen weak_ptr...

    edit: ok, zirkuläre vererbung geht nicht, weil beim vererben der ganze typ bekannt sein muss. ohne tricks geht das also nicht 😞



  • Skym0sh0 schrieb:

    haha, geht sowas eig?
    A erbt von B, B erbt von A?

    Wie soll das gehen? Eine der Klassendefinitionen ist zum Zeitpunkt zu dem geerbt werden soll zwangsläufig noch nicht vorhanden.



  • Nein, es ist keine Vererbung, sondern eine Komposition!



  • Matze1247 schrieb:

    Nein, es ist keine Vererbung, sondern eine Komposition!

    Geht genauso wenig. In einem A ist ein B. In einem B ist ein A. Also ist in einem A ein B, darin ein A, darin ein B, darin ein A,....

    Matze1247 schrieb:

    Es dürfen natürlich keine Zyklen auftreten, sonst wird der Speicher bei Shared Pointern nicht freigegeben.

    Dafür gibts weak_ptr. Aber was haben shared_ptr mit Komposition zu tun?

    Was willst du erreichen? (klar ausgedrückt, nicht mit A, B, C)



  • Kann man eigentlich noch ungenauere Fragen stellen?
    Sind A,B,C,D Namen von Objekten? Sind es Klassen?
    Was heißt "A->B"? Aus den Kontext scheint das hier etwas mit "Verlinkung" per Zeiger oder ähnliches zu tun zu haben.

    So oder so reicht das nicht, um dem Fragesteller helfen zu können.



  • krümelkacker schrieb:

    Kann man eigentlich noch ungenauere Fragen stellen?

    Was soll daran unpräzise sein? Die Frage ist recht klar und Skym0sh0 hat sie beantwortet.

    Aufbruch der zyklischen Referenz mit weak_ptr. Funktioniert wunderbar!



  • Hier übrigens ein kleines Codebeispiel:

    #ifndef _INTERFACE_H_
    #define _INTERFACE_H_
    
    #include <iostream>
    #include <memory>
    
    struct IA;
    struct IB;
    
    struct IA
    {
        virtual void SetIB(std::shared_ptr<IB> in_iB) = 0;
        virtual std::shared_ptr<IB> GetIB() = 0;
        virtual void Display() = 0;
    };
    
    struct IB
    {
        virtual void SetIA(std::shared_ptr<IA> in_iA) = 0;
        virtual std::shared_ptr<IA> GetIA() = 0;
        virtual void Display() = 0;
    };
    
    #endif
    
    #ifndef _IMPL_H_
    #define _IMPL_H_
    
    #include "Interface.h"
    
    struct A : public IA
    {
        A() { std::cout << "Constructor in A" << std::endl; }
        ~A() {  std::cout << "Destructor in A" << std::endl;  }
        void SetIB(std::shared_ptr<IB> in_iB) { m_iB = in_iB; }
        virtual std::shared_ptr<IB> GetIB() { return m_iB; }
        virtual void Display() { std::cout << "Hello from A" << std::endl; }
    
        std::shared_ptr<IB> m_iB;
    };
    
    struct B : public IB
    {
        B() { std::cout << "Constructor in B" << std::endl; }
        ~B() {  std::cout << "Destructor in B" << std::endl;  }
        void SetIA(std::shared_ptr<IA> in_iA) { m_iA = in_iA; }
        virtual std::shared_ptr<IA> GetIA() { return m_iA; }
        virtual void Display() { std::cout << "Hello from B" << std::endl; }
    
        std::shared_ptr<IA> m_iA;
    };
    
    #endif
    
    #include <iostream>
    #include "Impl.h"
    
    int main()
    {
        std::shared_ptr<A> a(new A());
        std::shared_ptr<B> b(new B());
    
        a->SetIB(b);
        //b->SetIA(a);    // Zyklus!
    
        a->Display();
        b->Display();
    
        return 0;
    }
    

    Setzt man b->SetIA(a); wird logischerweise kein Destruktor mehr aufgerufen.


Anmelden zum Antworten