Anzeige:
Ergebnis 1 bis 10 von 10

Thema: Polymorphismus in Vektoren erlaubt?

  1. #1
    Registrierter Benutzer Avatar von lokicall
    Registriert seit
    17.12.2005
    Beiträge
    53

    Polymorphismus in Vektoren erlaubt?

    Folgendes Problem:

    Gegegen acht Objekte(A-H) die alle von Objekt O erben und jeweils eine andere Methode m() implementieren(zT. auch andere Attribute). Nun will ich den Polymorphismus in einem Vektor nutzen.

    Denkansatz:
    vector<O> obj;
    obj.push_back(new A()); ... obj.push_back(new H());

    Alle Objekte(A-H) in den Vektor rein, um später dann obj.m() ausführen zu können. Ist das möglich?

  2. #2
    Registrierter Benutzer Avatar von panzi
    Registriert seit
    04.05.2001
    Ort
    Kottingbrunn
    Beiträge
    609
    Polymorphie geht nur über Pointer oder Referenzen. Ich würde hierbei sogar zu Smartpointer greifen, wenn das möglich ist.
    Intel Core 2 Duo CPU 2.66GHz; Nvidia GeForce 8 8800 GTS; 4GB RAM; Fedora 12; KDE-testing

  3. #3
    Administrator Avatar von anda_skoa
    Registriert seit
    17.11.2001
    Ort
    Graz, Österreich
    Beiträge
    5.477
    Im Grunde genommen hast du das auch schon in deiner Anfrage. d.h. die Objekte werden mit new angelegt, du hast lediglich noch eine falsche, inkompatible Vektor Deklaration.

    Code:
    vector<O*> obj;
    Bei Call-by-Value, also wenn du weder Pointer noch Referenzen benutzt, wird ja eine Kopie des Objekts erstellt. Wenn das Ziel der Kopie vom Typ deiner Basisklasse ist, ist jede Kopie nur mehr eine Instanz dieser Klasse, nicht mehr irgendeiner Subklasse.
    Das nennt man "Slicing"


    Ciao,
    _
    Qt/KDE Entwickler
    Debian Benutzer

  4. #4
    Registrierter Benutzer Avatar von lokicall
    Registriert seit
    17.12.2005
    Beiträge
    53
    Weiter gehts.

    Ich bekomme immer wieder Probleme in der Linkphase bzgl. Referenzauflösung und multiple Definitionen. Ein bissl Code zum erklären:

    Aus O.h
    Code:
    #ifndef _O_H
    #define _O_H
    
    class O {
            public:
                    virtual void m(void);
            protected:
                    int memptr;
    };
    
    void O::m() {}
    #endif
    Aus A.h
    Code:
    #include "O.h"
    
    class A:  public O {
            public:
                    A(int &memptr);
                    void m(void);
    };
    B.o:B.cpp:(.text+0x0): multiple definition of `O::m()'
    A.o:A.cpp:(.text+0x0): first defined here
    collect2: ld returned 1 exit status
    mingw32-make: *** [prog] Error 1
    Ich kann mit der Fehlermeldung nicht viel anfangen.

  5. #5
    Administrator Avatar von anda_skoa
    Registriert seit
    17.11.2001
    Ort
    Graz, Österreich
    Beiträge
    5.477
    Nachdem die Fehlermeldung B.cpp und A.cpp referenziert, kann man da nicht viel sagen.

    Ist das hier direktes Copy&Paste oder könntest du in deinem Code eventuell einen Include-Guard falsch haben und sich so eine Methodendefinition in mehreren Übersetzungeinheiten finden?

    Ciao,
    _
    Qt/KDE Entwickler
    Debian Benutzer

  6. #6
    Registrierter Benutzer Avatar von lokicall
    Registriert seit
    17.12.2005
    Beiträge
    53
    Der Compiler wollte m() als abstrakte Methode haben - typisch C++-Compiler, ausssagekräftige Fehlermeldungen sehen anders aus .
    Geändert von lokicall (27-06-2009 um 17:42 Uhr)

  7. #7
    Registrierter Benutzer
    Registriert seit
    23.05.2004
    Beiträge
    592
    Der Compiler wollte m() als abstrakte Methode haben - typisch C++-Compiler, ausssagekräftige Fehlermeldungen sehen anders aus
    Mal abgesehen davon, dass diese Meldung vom Linker kommt, ist sie doch ziemlich aussagekräftig gewesen - "multiple definition of O::m()" - und tatsächlich hattest du ja auch eine Definition im Header. Und den Header hast du wahrscheinlich mehrfach eingebunden (evtl. indirekt), oder?

  8. #8
    Registrierter Benutzer
    Registriert seit
    31.12.2008
    Beiträge
    34
    Ihr habt Probleme
    Code:
    class O {
      public:
        virtual void m() = 0;
    
    };
    
    class A : public O {
    
      public:
        void m() {
          cout << "In A\n";
        }
    };
    
    class B : public O {
    
      public:
        void m() {
          cout << "In B\n";
        }
    };
    
    int main() {
    
      vector<O*> vec;
      vec.push_back(new A());
      vec.push_back(new B());
      vec.push_back(new A());
    
      for(unsigned int i = 0; i < vec.size(); i++)
        vec[i]->m();
      return 0;
    }
    So ?

  9. #9
    Administrator Avatar von anda_skoa
    Registriert seit
    17.11.2001
    Ort
    Graz, Österreich
    Beiträge
    5.477
    Zitat Zitat von lokicall Beitrag anzeigen
    Der Compiler wollte m() als abstrakte Methode haben
    Das geht auch ohne abstrakte Methode, wie man durch entsprechende Änderung in katers Beispielcode leicht überprüfen kann.

    Es ist nur wie auch bei normalen Methoden oder Funktionen darauf zu achten, dass die Symboldefinition nur in einer Objektdatei stattfindet (das virtual Schlüsselwort ändert an dieser Anforderung gar nichts).
    Ob das nun durch eine Definition in einer .cpp Datei oder durch inline Definition in der Klassendeklaration erfolgt, spielt dabei keine Rolle.

    Ciao,
    _
    Qt/KDE Entwickler
    Debian Benutzer

  10. #10
    Registrierter Benutzer Avatar von panzi
    Registriert seit
    04.05.2001
    Ort
    Kottingbrunn
    Beiträge
    609
    Zitat Zitat von kater Beitrag anzeigen
    Ihr habt Probleme
    Code:
    class O {
      public:
        virtual void m() = 0;
    
    };
    
    class A : public O {
    
      public:
        void m() {
          cout << "In A\n";
        }
    };
    
    class B : public O {
    
      public:
        void m() {
          cout << "In B\n";
        }
    };
    
    int main() {
    
      vector<O*> vec;
      vec.push_back(new A());
      vec.push_back(new B());
      vec.push_back(new A());
    
      for(unsigned int i = 0; i < vec.size(); i++)
        vec[i]->m();
      return 0;
    }
    So ?
    Nur ist darauf zu achten, dass man normalerweise die ganzen Objekte auch wieder manuell per delete freigeben muss, ansonsten hast ein fettes Speicherleck. Deswegen hab ich ja auch das mit den Smartpointern gemeint.
    Intel Core 2 Duo CPU 2.66GHz; Nvidia GeForce 8 8800 GTS; 4GB RAM; Fedora 12; KDE-testing

Lesezeichen

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •