Aufruf einer vector-Klassenvariable aus einer Methode



  • Ich habe das Problem, dass ich aus einer Klassenmethode nicht auf eine Klassenvariable vom Typ vector<AndereKlasse> zugreifen kann.

    //data.hpp
    
    class Service {...};
    
    class Data
    {
    private:
       std::vector<Service> services;
    public:
       Data();
       void doSomething();
       //...
    };
    
    //data.cpp
    Data::Data()
    {}
    
    void Data::doSomething()
    {
       vector<Service> localServices;
       Service a = new Service();
       localServices.push_back(a);
    
       Service b = new Service();
       services.push_back(b);
    }
    
    //...Aufruf von doSomething()
    

    Das Erzeugen des neuen Service a und Hinzufügen zu dem lokalen vector localServices funktioniert problemlos. Wenn ich aber den neuen vector b zur Klassenvariable services hinzufügen möchte, bekomme ich in der compile time einen Systemfehler und das Programm bricht ab.

    1.) Was kann ich tun? Muss services noch initialisiert werden? Wie? Fehlt sonst noch irgendetwas?
    2.) Sollte ich generell lieber einen vector von Pointern auf Objekte anlegen?

    vector<Service*> Services;
    

    Ich bin dankbar für jede Hilfe.
    TommyT



  • Wenn du einen Compilerfehler erhälst, wäre es nett, diesen auch zu posten.

    Wenn ich deinen Code ein bisschen ins Reine schreib, kompilierts bei mir (MSVC 2008):

    #include <vector>
    using namespace std;
    
    class Service {};
    
    class Data
    {
    private:
       std::vector<Service> services;
    public:
       Data();
       void doSomething();
       //...
    };
    
    //data.cpp
    Data::Data()
    {}
    
    void Data::doSomething()
    {
       vector<Service> localServices;
       localServices.push_back(Service());
    
       services.push_back(Service());
    }
    
    //...Aufruf von doSomething() 
    int main()
    {
    	Data data;
    	data.doSomething();
    }
    

    Zu deinen Fragen: Nein, nein und nein.



  • TommyT schrieb:

    Wenn ich aber den neuen vector b zur Klassenvariable services hinzufügen möchte, bekomme ich in der compile time einen Systemfehler und das Programm bricht ab

    Was nun: Laufzeit (nur dort kann das Programm abbrechen) oder während der Kompilierung (dort kann die Kompilierung, nicht aber das Programm abbrechen).

    Im letzteren Fall bekommst du vom Compiler eine aussagekräftige Fehlermeldung die du uns hier verheimlichst.

    Und das folgendes nicht funktioniert ist recht logisch: Elemente die auf dem Heap angelegt werden, werden über Zeiger verwaltet.

    // Fehler:
    Service a = new Service();  // new Service() liefert einen Zeiger zurück
    
    // Richtig (einmal als Stackvariable, einmal über Zeiger & Heap)
    Service b; // Auf dem Stack, mittels Standardkonstruktor
    Service * c = new Service(); // Auf dem Heap
    

    Dann rate auch mal, wann du einen std::vector<Service> und wann einen std::vector<Service*> brauchst... (Im Ersten Fall wird aber mit vielen Kopien gearbeitet, in letzteren musst du dafür die Freigabe selbst erledigen).

    cu André



  • Sorry für die Verwirrung.
    Das Program bricht mit einem nicht spezifizierten Windows-Error ab, dementsprechend Laufzeitfehler.

    Schonmal danke für den Hinweis zur Verwendung von new&co.

    Ich verstehe nur nicht warum eine Zuweisung innerhalb der Methode funktioniert, es aber einen Fehler gibt, wenn der Vector class member ist.



  • TommyT schrieb:

    Sorry für die Verwirrung.
    Das Program bricht mit einem nicht spezifizierten Windows-Error ab, dementsprechend Laufzeitfehler.

    Dein Originalcode hätte meiner Meinung nach garnicht erst compiliert werden dürfen. Es sei den dein Beispiel ist zu stark verkürzt und du hast z.B. noch einen Konstruktor der einen Zeiger oder ähnliches annimmt.

    Dein Programm (mit einer leeren Serviceklasse) liefert bei mir den folgenden Fehler:

    error C2440: 'Initialisierung': 'Service *' kann nicht in 'Service' konvertiert werden
    

    Wenn du aber einen solchen Konstruktor anbietest...

    Service(Service * p);
    

    ...wäre das geschilderte Verhalten vermutlich zu erklären, da dieser vermutlich ungewollt aufgerufen wird...

    Falls aber dein Compiler bereits folgenden Code zulässt, AUSTAUSCHEN:

    // Compiler sofort austauschen, wenn er folgendes ohne Warnungen oder Fehler compiliert!!!
    #include <vector>
    
    class Service {};
    
    int main()
    {
       std::vector<Service> services;
       Service b = new Service();
       services.push_back(b);
    }
    

    cu André
    P.S: Aus reiner Neugier: Welcher Compiler und welche Compilerversion (Alternativ wenn IDE und Compiler gekoppelt sind, deren Bezeichnung und Version).



  • Halle André,

    Nein eine leere Klasse verwendete ich nicht, daher hatte ich oben auch

    class Service {...};
    

    gepostet. Die Pünktchen sind in dem Antwortpost aber leider entschwunden.

    Tatsächlich stellt die Klasse verschiedene - hier nicht wichtige Attribute und Methoden - zur Verfügung.

    Ich verwende Dev-C++ 4.9.9.2 mit gcc 3.4.2. Das Kompilieren deines Beispiels erzeugt erwartungsgemäß den Fehler

    conversion from `Service*' to non-scalar type `Service' requested
    

    Bye.
    Thomas



  • Ich habe jetzt die Erzeugung der Service-Instanzen sowohl über den Heap, als auch über den Stack versucht. Dieser Punkt ist jetzt klar.

    Das Problem tritt allerdings schon früher auf:

    //data.hpp 
    
    class Service {
    //...
    }; 
    
    class Data 
    { 
    private: 
       std::vector<Service> services; 
    public: 
       Data(); 
       void doSomething(); 
       //... 
    }; 
    
    //data.cpp 
    Data::Data() 
    {} 
    
    void Data::doSomething() 
    { 
       std::vector<Service>::iterator it;
       it = services.begin(); 
    } 
    
    //...Aufruf von doSomething()
    

    Dies erzeugt wieder einen Runtime Error.

    Könnte es sein, dass der vector hier Probleme mit dem Index hat? Müsste man den vector irgendwie initialisieren?



  • Naja, wenn keine einträge in dem Service-Vector sind, und du irgendwas mit NULL anstellst, gibts ebend ein Fehler :Dwäre also schon schön wenn du den vector mit services füllst.



  • Würde ich ja gerne. Aber

    Service s;
    services.push_back(s);
    

    funktioniert ja eben auch nicht.



  • Zeig mal deine komplette Deklaration. Weil das verwundert mich jetzt sehr.



  • TommyT schrieb:

    Würde ich ja gerne. Aber ... funktioniert ja eben auch nicht.

    Hallo Doktor, mir tuts irgendwo so merkwürdig weh, wobei es auch kein Schmerz sein könnte, und ich weiß nicht so recht wo.



  • asc schrieb:

    TommyT schrieb:

    Würde ich ja gerne. Aber ... funktioniert ja eben auch nicht.

    Hierbei bezog ich mich auf auf unseren vorhergehenden Dialog.

    Ich habe das Problem nun endlich gelöst.
    Verantwortlich waren die folgenden beiden Punkte:

    1.) Bei der Definition der Service-Klasse

    class Service { 
    //... 
    };
    

    gab es außschließlich einen Konstruktor, welcher verschiedene Argumente verlangt hat. Hier musste noch ein Default-Konstruktur angelegt werden.

    Service::Service() {}
    
    Service::Service(int id, int startTime, int endTime, int startStation, int endStation, int dist) 
    {
    //...
    }
    

    2.) Die Klasse Data ist nicht korrekt instanziert worden (bzw. die Instanz ist nicht korrekt weitergeleitet worden), so dass bei dem Aufruf von myData.doSomething() Ungereimtheiten aufgetreten sind.

    Ich bin froh, dass ich euch das Posten des gesamten Codes nun ersparen konnte und danke euch für eure tatkräftige Unterstützung, insbesondere da ich weiß, dass man es mit einem C++-Neuling wie mir nicht immer leicht hat.

    Danke und Bye
    Thomas



  • TommyT schrieb:

    Hierbei bezog ich mich auf auf unseren vorhergehenden Dialog.

    Das ist mir bewusst, aber "funktioniert nicht" akzeptieren hier viele nicht als Aussage (ich auch nicht). Weder nennst du Fehlermeldungen noch sonstige sinnvolle Angaben.

    Bitte in Zukunft genauere Angaben machen.

    cu André


Log in to reply