A refference of Type [...] (not const-qualified) cannot be initialized with a value of [...]



  • Hey Leute,

    bei der Implementierung eines Vectors bin ich auf ein Problem gestoßen:
    Folgende Klassen sind Teil meines Vorhabens:

    class A
    {
    ...
    };
    
    class B : public A
    {
    ...
    };
    
    class C : public A
    {
    ...
    };
    

    Nun möchte ich einen Vector als einen Speicher der Klassen haben, jedoch sollen beide Klassen vertreten sein. Also erstelle ich folgenden Vector:

    std::vector<A> vec;
    

    Nun möchte ich mit einer for Schleife das erste B in diesem Vector vec finden, welcher Objekte vom Typ B und C enthält:

    B & getFirstB(){
         for(int i = 0; i < vec.size(); i++)
         {
              if(typeid(vec.at(i)) == typeid(B))return vec.at(i);
         }
    }
    

    Jedoch bekomme ich jene Bemerkung angezeigt:

    A refference of Type "B&" (not const-qualified) cannot be initialized with a value of "A"

    Ich brauche jedoch die Referenz, da ich in folgenden Implementierung ähnliche Vorgehensweisen z.B. mit Spiel-Inventaren nutzen wollte, und die Gegenstände in so einem Inventar nach z.B. Gebrauch schließlich erhalten bleiben sollen.
    Was soll mir dieser Error sagen und was muss ich verändern?

    crsf1re


  • Mod

    Passt evtl. besser ins C++ Forum.

    crsf1re schrieb:

    A refference of Type "B&" (not const-qualified) cannot be initialized with a value of "A"

    Was soll mir dieser Error sagen und was muss ich verändern?

    Jedes B ist ein A, aber nicht jedes A ein B. C++ ist ein statisch typisierte Sprache: um zu entscheiden, ob etwa eine Referenz mit einem bestimmten Wert kompatibel ist, kommt es nur auf die deklarierten Typen an, nicht auf den konkreten Inhalt, der erst beim Programmablauf feststeht. Zudem wird die Frage der Komaptibilität lokal entschieden, es kommt nicht darauf an, ob der Programmier etwa durch Programmverzweigungen Sorge dafür getragen hat, dass nur mit kompatiblen Werten gearbeitet wird. Allerdings steht die Möglichkeit offen, den Typ eines Ausdrucks explizit zu ändern (=Cast). In diesem Fall, sorgt das if dafür, dass das return Statement sicher nur dann ausgeführt wird, wenn der (dynamische) Typ (ich gehe mal davon aus, dass A polymorph ist) des gespeicherten Objektes passt.
    In diesem Fall gibt es die Möglichkeit, static_cast einzusetzen:

    return static_cast<B&>(vec.at(i));
    

    Problematisch ist allerdings zusätzlich, dass diese if-Bedingung tatsächlich nie erfüllt sein kann:
    vec speichert nur A-Objekte, solltest versuchen ihn mit Objekten abgleiteter Klassen zu füllen, wird er ohne zu Klagen nur den A-Basisklassenteil dieser Objekte kopieren und den Rest wegwerfen (=Slicing).



  • Dieser Thread wurde von Moderator/in SeppJ aus dem Forum Rund um die Programmierung in das Forum C++ (alle ISO-Standards) verschoben.

    Im Zweifelsfall bitte auch folgende Hinweise beachten:
    C/C++ Forum :: FAQ - Sonstiges :: Wohin mit meiner Frage?

    Dieses Posting wurde automatisch erzeugt.



  • Ich denke, daß hier eher ein

    std::vector<A*> vec;
    

    oder

    std::vector<unique_ptr<A>> vec;
    

    verwendet werden muss.

    @crsf1re: Dir ist wahrscheinlich gar nicht klar, was das von Camper angesprochene Slicing bedeutet?


Anmelden zum Antworten