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.