Referenz zeigt ins Nirvana



  • Hi SeppJ,

    also ein Cluster ist sozusagen verantwortlich für die Verwaltung von einer Reihe von Peers, als C abgekürzt.

    Es passiert folgendes, hier mal im groben Ablauf dargestellt:

    Cluster c = createCluster();
    c.getID(); // --> ID = 0
    c.addPeer(0);
    c.getPeer(0).getClusterID(); // --> ID = -123123231
    c.getClusterID(); // --> ID = 0

    Die Indirektion über den ClusterReferrer ist eingefügt, damit sich zum Beispiel ein Peer nicht selbst aus dem Cluster entfernen kann. Daher soll er nur einen beschränkten Zugriff auf Infos von Cluster haben. Wie sich die Referenz auf dem Cluster im ClusterReferrer ändern kann versteh ich auch nicht. Ich benutze gerade Referenzen um NullPointer u.ä. zu vermeiden.

    😞



  • hmmm....

    Da kann ich mich wohl von meinem Geld verabschieden...

    Sieht nach nicht implementierter operator=() aus, oder?



  • Das hier:

    uwerothfeld schrieb:

    [...]

    Cluster::Cluster(ClusterID cId, GroupReferrer * gRef):cRef(*this) {
    ...
    }
    

    [...]

    kann schief gehen, je nachdem, was cRef mit dem übergebenen Objekt so treibt. this ist an der Stelle, an der Du es benutzt noch gar nicht vollständig konstruiert (du bist ja noch im Ctor). Das führt dazu, dass cRef u.U. auf irgendwelchem uninitialisierten Zeugs rumhobelt.
    Eigentlich sollte Dich Dein Compiler da auch warnen.



  • Mh gute Frage,

    also ich habe im Cluster nen operator=, das gleiche gilt für Peer und ClusterReferrer. Wo sollte ich da noch ein operator= definieren?

    Tachyon schrieb:

    Das hier:

    uwerothfeld schrieb:

    [...]

    Cluster::Cluster(ClusterID cId, GroupReferrer * gRef):cRef(*this) {
    ...
    }
    

    [...]

    kann schief gehen, je nachdem, was cRef mit dem übergebenen Objekt so treibt. this ist an der Stelle, an der Du es benutzt noch gar nicht vollständig konstruiert (du bist ja noch im Ctor). Das führt dazu, dass cRef u.U. auf irgendwelchem uninitialisierten Zeugs rumhobelt.
    Eigentlich sollte Dich Dein Compiler da auch warnen.

    Und wie behebe ich dies? Doch zurück zu Pointern?


  • Administrator

    uwerothfeld schrieb:

    Ich benutze gerade Referenzen um NullPointer u.ä. zu vermeiden.

    Referenzen sind nicht einfach Zeiger ohne Möglichkeit den Wert Null zu haben. Einfach pauschal Referenzen zu verwenden, nur um die Möglichkeit von Nullzeiger zu verhindern, ist definitiv der falsche Weg und nicht das, wofür Referenzen gedacht sind.

    Übrigens hast du immer noch nicht erklärt, was nun der Typ Cluster in deinem Code darstellt. Du hast einen Typ C und einen Typ Cluster . Oder ist das ein Schreibfehler von deiner Seite und beide Typen sind die gleichen?
    Und wie sehen deine operator= denn aus?

    Grüssli



  • Dravere schrieb:

    Und wie sehen deine operator= denn aus?

    Genau...

    Kopierst du auch alle Objekte, auf die im Objekt verwiesen wird und im
    Destruktor gelöscht werden?



  • Hi,

    ja Cluster ist gleich C! Sorry. Also hier nochmal meine operator= für die einzelnen Teilnehmer:
    Klasse Cluster:

    Cluster & Cluster::operator=(const Cluster &rhs){
    
                peerList = rhs.peerList;
                clusterId = rhs.clusterId;
    
                cRef = rhs.cRef;
                groupReferrer = rhs.groupReferrer;
                masterReferrer = rhs.masterReferrer;
    
                return *this;
    
            }//End operator=
    

    Klasse Peer:

    Peer & Peer::operator=(const Peer &rhs) {
    
                peerId = rhs.peerId;
                role = rhs.role;
                ta = rhs.ta;
                state = rhs.state;
                currCluster = rhs.currCluster;
    
                return *this;
    
            }//End operator=
    

    Klasse ClusterReferrer:

    ClusterReferrer & ClusterReferrer::operator = (const ClusterReferrer &rhs){   
    
                cluster = rhs.cluster;
    
                return *this;
    
            }//End operator=
    


  • uwerothfeld schrieb:

    [...]Und wie behebe ich dies? Doch zurück zu Pointern?

    Zum Beispiel, ja:

    Cluster::Cluster(ClusterID cId, GroupReferrer * gRef) : //alles initialisieren
    {
       //weiter initialisieren, sofern in Initliste nicht moeglich
       cRef.reset(new ClusterReferrer(*this)); //std::tr1::scoped_ptr<ClusterReferrer>
    }
    


  • Achso: Zeig mal den Ctor von ClusterReferrer .



  • Wird

    ClusterReferrer * currCluster;
    

    im Destruktor gelöscht?



  • Hallo,
    was meinst du damit:

    Cluster::Cluster(ClusterID cId, GroupReferrer * gRef) : //alles initialisieren
    {
       //weiter initialisieren, sofern in Initliste nicht moeglich
       cRef.reset(new ClusterReferrer(*this)); //std::tr1::scoped_ptr<ClusterReferrer>
    }
    

    [/quote]
    Boost kann ich leider nicht verwenden. Ist reset sowas wie:

    void ClusterReferrer::reset(ClusterReferrer * a){
    this = a;
    }
    

    ???

    der Constructor von ClusterReferrer sieht jetzt so aus:

    ClusterReferrer::ClusterReferrer(Cluster * c):cluster(c){
            }//End ClusterReferrer
    

    der von Cluster so:

    Cluster::Cluster(ClusterID cId, GroupReferrer * gRef):clusterId(cId), groupReferrer(0), masterReferrer(0), clusterReferrer(this) {
    std::cout<<"### CONSTRUCTOR: cluster ref daten für cluster "<<clusterId<<": "<<clusterReferrer.getClusterID()<<std::endl;
    //gibt das richtige aus, komischer weise
            }//End Cluster
    

    Den Peer füge ich hinzu über:

    void Cluster::addPeer(Peer & peer) {
    
                //setup peer
                //@bug
    std::cout<<"### ADD PEER: cluster ref daten für cluster "<<clusterId<<": "<<clusterReferrer.getClusterID()<<std::endl; //hier ist es falsch
                peer.setCurrentCluster(&clusterReferrer);
    std::cout<<"id lokal :"<<this->clusterId<<" peer cluster ID "<< peer.getClusterID()<<std::endl;
     ....
    }
    

    Der Fehler ist bestimmt billig. Aber wie billig genau?

    CSpille schrieb:

    Wird

    ClusterReferrer * currCluster;
    

    im Destruktor gelöscht?

    Beim Peer? Nein, da es ja innerhalb von Cluster als Member liegt, als nicht als Heap-Objekt. Ist dies falsch?


Anmelden zum Antworten