Vector aus Objekten -> auf Objekte über den Iterator zugreifen und verändern



  • Ehrlich gesagt denke ich, dass du dir ganz dringend noch mal ein Grundlagen Buch ansehen solltest. Vielleicht kannst du schon eine andere Sprache und probierst ein bischen C++ aus? Wenn Du noch keins hast, besorg dir mal ein gutes Buch (C++ Primer z.B.).

    Zu Deinen Fragen:
    Instanzen von Klassen übergibt man meistens oder fast immer als konstante Referenz (const string&). Das ist, was in den vielen anderen Sprachen automatisch passiert, da dort alles eine Referenz ist. In C++ bedeutet die Signatur (string label) aber, dass hier eine Kopie vom string übergeben wird. Um die Kopie einzusparen übergibt man eine Referenz. Und const, damit man das Original nicht verändert kann.

    ElementVector ist ein vector<Element*>. Ein ElementVector::iterator ist ein vector<Element*>::iterator. Der * Operator des ElementVector::iterator gibt eine Referenz auf ein Element* zurück.

    (*it)->SetTransparenz(4);
    

    ruft also die Methode SetTransparenz mit einem Element* auf. Der Compiler sucht also Element::SetTransparenz. So eine Funktion existiert nicht, denn SetTransparenz hast du in der Kreisklasse definiert. Wenn Du SetTransparent mit einem Element* aufrufen möchtest, muss diese Methode in der Schnittstelle von Element vorhanden sein. Das bedeutet dann aber, dass alle Elemente eine Transparenz zugeordnet bekommen können. Wenn das eine reine Kreiseigenschaft ist, musst du dir etwas anderes überlegen. Mit einem Elemen* hast du nur Zugriff auf die Element Schnittstelle, du kannst also nur das machen, was alle Arten von Elementen betrifft.



  • Das könnte man z.Bsp. mit einem dynamic_cast lösen (ist aber eigentlich kein guter Stil).

    if (it != elements.end()) { // etwas gefunden?
        Kreis* kreis = dynamic_cast<Kreis*>(*it); // versucht Element* in Kreis* zu verwandeln
        if( kreis != 0) // Ja es ist ein Kreis
            kreis->SetTransparenz(4);
    }
    


  • @brotbernd: Ja, du hast es auf den Punkt gebracht. Ich bin Newbie in C++, und weil in dem Buch durch welches ich mich durchgearbeitet habe nichts demgleichen vorkam, hab ich es auch nicht vermisst, weil ich es aus meinen Sprachen nicht kenne. Unglücklich - aber aus Fehlern lernt man.

    Für den Fall dass jemand an derselben Stelle Schwierigkeiten hat:
    Das 'Problem' habe ich anders gelöst, ich habe die Objekte der abgeleiteten Klassen jeweils in einen eigenen Vektor gepackt. Das hat sich auch für den weiteren Verlauf als vorteilhaft erwiesen, da man auf der Suche nach einem Objekt nur den Vektor genau dieser Objekte durchsuchen muß und nicht den (möglicherweise um ein Mehrfaches) größeren Vektor aller Objekte.

    Es belibt eine Stelle offen, und den Fehlre bekomme ich nicht mehr weg (was ich einige Posts weiter oben geschrieben habe)

    struct FindObj{
    private:
        string SearchString_;
    public:
        FindObj(string Name) : SearchString_(Name){}
        bool operator()(const ElemGeomForm& findForm){
            return findForm->Label == SearchString_;
        }
    };
    

    aufgerufen mit

    string Label_ = FileLine.substr(18, 50);
    vector<ElemGeomForm>::iterator itElem = find_if(ElemVec.begin(), ElemVec.end(), FindObj(Label_));
    

    gibt folgenden Fehler zurück:

    1>error C2440: '<function-style-cast>' : cannot convert from 'std::string' to 'Parser::FindObj'
    1> Source or target has incomplete type

    Fällt jemandem was dazu ein?



  • struct FindObj{
    private:
        string SearchString_;
    public:
        FindObj(string Name) : SearchString_(Name){}
        bool operator()(const ElemGeomForm& findForm){
            return findForm->Label == SearchString_;
        }
    };
    

    aufgerufen mit

    string Label_ = FileLine.substr(18, 50);
    
    FindObj fo(Label_);
    
    vector<ElemGeomForm>::iterator itElem = find_if(ElemVec.begin(), ElemVec.end(), fo);
    


  • Aaaalso:

    Du hast doch hier
    vector<ElemGeomForm>::iterator itElem = find_if(ElemVec.begin(), ElemVec.end(), FindObj(Label_));
    einen Vektor mit Elementen vom Typ ElemGeomForm.
    Hier:
    vector<ElemGeomForm>::iterator itElem = find_if(ElemVec.begin(), ElemVec.end(), FindObj(Label_));
    wird der Operator () des temporär erstellten FindObj - Objektes aufgerufen, dem ein solches ElemGeomForm als Parameter mitgegeben wird.
    Hier:
    bool operator()(const ElemGeomForm& findForm){
    return findForm->Label == SearchString_;
    }
    tust Du aber so, als hättest Du nicht ein ElemGeomForm - Element, sondern einen Zeiger auf ein solches - Du benutzt nämlich den -> Operator anstelle des . Operators.

    Da ich anfangs des Threads den Eindruck gewonnen habe, Du weißt selber nicht, was von beiden nun richtig ist, kann ich Dir mehr auch nicht dazu sagen.
    Aber eines von beiden muß falsch sein.



  • Ich hab im Laufe letzter Woche ziemlich oft was an diesem Vector verändert, aktuell ist es ein Vector aus Zeigern, der auch den Fehler verursacht. Ich definiere dann das struct so:

    struct FindObj{
    private:
        string SearchString_;
    public:
        FindObj(string Name) : SearchString_(Name){}
        bool operator()(ElemGeomForm* findForm){
            return findForm->Label == SearchString_;
        }
    };
    

    und ruf es auf mit

    std::vector<ElemGeomForm*>::iterator itElem = find_if(ElemVec.begin(), ElemVec.end(), FindObj(Label_));
    

    Also wird das erstellte FindObj-Objekt aufgerufen, indem ihm der Zeiger auf dem jeweiligen Objekt mitgegeben wird. Kann das der Grund sein? Es heißt ja "cannot convert from 'std::string' to 'Parser::FindObj'". Aber wie kann ich das korrigieren?


Anmelden zum Antworten