Anzeige:
Seite 1 von 2 12 LetzteLetzte
Ergebnis 1 bis 15 von 28

Thema: C++ und "virtual"

  1. #1
    Registrierter Benutzer
    Registriert seit
    19.04.2003
    Beiträge
    194

    Post C++ und "virtual"

    Hallo!

    Angenommen ich habe eine Klasse welche Funktionen enthält die "virtual" sind, dann müssen diese ja in den abgeleiteten "überschrieben" also definiert werden. Will ich jedoch nun von der Klasse, die die virtuellen Funktionen enthält, ein Objekt (mit new) erstellen, so bekomm ich vom g++ immer die Meldung
    Code:
    error: cannot allocate an object of type ` Mitarbeiter' 
    error: because the following virtual functions are abstract:
    Oder auch wenn ich kein Objekt erstellen will und nur zb ein Array von der Klasse um später die Objekte von den abgeleiteten Klasse dort hin zu "referenzieren" funkt nicht! Ist das Wort "virtual" so ca. mit "abstract" von Java gleich zu setzen?!? Hab auch gehört wenn man eine Funktion "virtual" setzt, dann ist das jede Funktion von dieser Klasse! Stimmt das auch?!?

    mfG
    Going to church does not make a person religious, nor does going to school make a person educated, any more than going to a garage makes a person a car.

  2. #2
    Registrierter Benutzer
    Registriert seit
    11.07.2004
    Beiträge
    8
    Zitat Zitat von Silver
    Angenommen ich habe eine Klasse welche Funktionen enthält die "virtual" sind, dann müssen diese ja in den abgeleiteten "überschrieben" also definiert werden.
    Nein. Nur wenn sie abstrakt sind.
    Zitat Zitat von Silver
    error: cannot allocate an object of type ` Mitarbeiter'
    error: because the following virtual functions are abstract:
    Weil du sie abstrakt gemacht hast (mit =0).
    Zitat Zitat von Silver
    Ist das Wort "virtual" so ca. mit "abstract" von Java gleich zu setzen?!?
    Nein, in Java ist einfach jede Funktion virtual.
    Zitat Zitat von Silver
    Hab auch gehört wenn man eine Funktion "virtual" setzt, dann ist das jede Funktion von dieser Klasse! Stimmt das auch?!?
    Nein.

  3. #3
    Registrierter Benutzer
    Registriert seit
    19.04.2003
    Beiträge
    194
    cool danke !

    aber was bedeutet nun virtual ohne dem =0 ?!?

    mfG
    Going to church does not make a person religious, nor does going to school make a person educated, any more than going to a garage makes a person a car.

  4. #4
    Registrierter Benutzer Avatar von tuxipuxi
    Registriert seit
    30.08.2002
    Beiträge
    667
    Eine virtuelle Funktion kann eine Funktionsbody haben, dann musst du die Funktion in der subclass nicht überschreiben.
    Wenn du die Funktion abstrakt, das heißt =0 machst, _muss_ jede subclass die Funktion implementieren, sonst ist das immer noch eine abstrakte Klasse von der man kein Objekt instanziieren kann.

    Michael.

    P.S: Vielleicht solltest du in deiner Signatur ein bisschen zwischen Regierung und gesamten Volk differenzieren, so klingt es ein wenig platt.

  5. #5
    Registrierter Benutzer
    Registriert seit
    19.04.2003
    Beiträge
    194
    Zitat Zitat von tuxipuxi
    Eine virtuelle Funktion kann eine Funktionsbody haben, dann musst du die Funktion in der subclass nicht überschreiben.
    aha danke, aber was bedeutet nun wenn man eine Funktion virtuell macht und nicht abstrakt?!? Kenne nur abstrakte Klassen von Java aus...

    mfG
    Going to church does not make a person religious, nor does going to school make a person educated, any more than going to a garage makes a person a car.

  6. #6
    Registrierter Benutzer
    Registriert seit
    05.09.2002
    Ort
    Neuhausen
    Beiträge
    320
    Folgendes Programm illustriert die Auswirkungen von virtual:
    Code:
    #include <iostream>
    
    class Foo {
    public:
        void called() { std::cout << "  Foo::called()" << std::endl; }
        virtual void vcalled() { std::cout << "  Foo::vcalled()" << std::endl; }
        void methode1() {
            std::cout << "Foo::methode1():" << std::endl;
            this->called(); this->vcalled();
        }
    };
    class Bar : Foo {
    public:
        void called() { std::cout << "  Bar::called()" << std::endl; }
        virtual void vcalled() { std::cout << "  Bar::vcalled()" << std::endl; }
        void methode2() {
            std::cout << "Bar::methode2():" << std::endl;
            this->called(); this->vcalled();
        }
        void methode3() {
            std::cout << "Bar::methode3():" << std::endl;
            Foo::called(); Foo::vcalled();
        }
        void methode4() {
            std::cout << "Bar::methode4():" << std::endl;
            this->methode1();
        }
    };
    
    int main() {
        Foo f;
        Bar b;
        f.methode1();
        b.methode2();
        b.methode3();
        b.methode4();
        return EXIT_SUCCESS;
    }
    Ausgabe:
    Code:
    Foo::methode1():
      Foo::called()
      Foo::vcalled()
    Bar::methode2():
      Bar::called()
      Bar::vcalled()
    Bar::methode3():
      Foo::called()
      Foo::vcalled()
    Bar::methode4():
    Foo::methode1():
      Foo::called()
      Bar::vcalled()
    Virtuelle Methoden werden nicht direkt aufgerufen, sonderen über die Virtuelle Methodentabelle des Objekts. In dieser wird so immer die Adresse der Methode abgelegt, welche in der instanzierten Klasse definiert ist.

    Im Beispiel oben kommt das im Letzten Methodenaufruf b.methode4() zum Ausdruck: Eine nicht virtuelle Methode called() wird immer diejenige der gleichen Klasse aufgerufen, während die viruelle Methode vcalled() der instanzierten Klasse Bar aufgerufen wird, obwohl Foo noch nichts von dieser Methode wissen muss.

    Eine virtuelle Klasse ist daher ein unverzichtbares Werkzeug für polymorphe Klassen.

    Gruss, Andy

  7. #7
    Registrierter Benutzer
    Registriert seit
    16.09.2001
    Beiträge
    1.182

    Bin aber auch ein schlimmer ;-)

    Java ist daher ein unverzichtbares Werkzeug für objecktierientierte Programmierung.
    .................................................. ............

  8. #8
    Registrierter Benutzer
    Registriert seit
    19.04.2003
    Beiträge
    194
    Hallo!

    Hab noch ein paar Fragen!
    Angenommen ich habe eine Klasse:
    Code:
    class Auto {
    	public:
    	virtual void getKosten =0;
    };
    warum kann ich dann von dieser Klasse zb kein Array Objekt machen (Auto auto_array[10]) oder auch nur Objekt um dann später in diesem Array die abgeleiteten Objekte zu speichern? In Java funkt das! Was wäre ein anderer Lösungsvorschlag?!?

    Hab noch ein Problem: Hab eine Klasse Mitarbeiter und eine Klasse Arbeiter welche von Mitarbeiter ableitet. Schreibe ich nun eine Methode welches eine Eigenschaft zurückgibt, bekomm ich folgenden Compiler-fehler:
    Code:
    mitarbeiter.o(.gnu.linkonce.r._ZTI12Angestellter+0x8):mitarbeiter.cpp:17: undefined reference to `typeinfo for Mitarbeiter'

    Vielen Dank für eure Antworten!


    PS: Hätte nicht gedacht, dass der Sprung von Java auf C++ soviele Probleme bereitet....
    Going to church does not make a person religious, nor does going to school make a person educated, any more than going to a garage makes a person a car.

  9. #9
    Registrierter Benutzer
    Registriert seit
    11.07.2004
    Beiträge
    8
    Zitat Zitat von Silver
    warum kann ich dann von dieser Klasse zb kein Array Objekt machen (Auto auto_array[10]) oder auch nur Objekt um dann später in diesem Array die abgeleiteten Objekte zu speichern? In Java funkt das!
    Wenn du das willst, was du in Java hast, dann brauchst du ein Array von Auto*.

    Zitat Zitat von Silver
    Code:
    mitarbeiter.o(.gnu.linkonce.r._ZTI12Angestellter+0x8):mitarbeiter.cpp:17: undefined reference to `typeinfo for Mitarbeiter'
    Hast du mit g++ gelinkt?

  10. #10
    Registrierter Benutzer
    Registriert seit
    23.05.2004
    Beiträge
    592
    Gegeben ist eine abstrakte Klasse:
    warum kann ich dann von dieser Klasse zb kein Array Objekt machen (Auto auto_array[10]) oder auch nur Objekt um dann später in diesem Array die abgeleiteten Objekte zu speichern?
    Du hast ja extra eine abstrakte Klasse gemacht, damit du kein Objekt davon direkt machen kannst!

    Zur "undefined refererence for vtable...":
    Du musst sicherstellen das die Übersetzungseinheit in der eine virtuelle Funktion (für pure-virtual gilt das nicht) zu deinem Programm gehört. Also entweder muss in der einzigen Übersetzungseinheit die Definition vorhanden sein, oder es muss diejenige Übersetzungeinheit welche die Definition enthält hinzugelinkt werden. Der Grund dafür ist, dass der gcc (grob gesagt) die "vtable" zusammen mit der Definiton von virtuellen Funktionen emittiert.
    (Also insbesondere bitte beachten das das für andere Compiler nicht unbedingt gelten muss).

  11. #11
    Registrierter Benutzer
    Registriert seit
    19.04.2003
    Beiträge
    194
    Zitat Zitat von locus vivendi
    Zur "undefined refererence for vtable...":
    Du musst sicherstellen das die Übersetzungseinheit in der eine virtuelle Funktion (für pure-virtual gilt das nicht) zu deinem Programm gehört. Also entweder muss in der einzigen Übersetzungseinheit die Definition vorhanden sein, oder es muss diejenige Übersetzungeinheit welche die Definition enthält hinzugelinkt werden. Der Grund dafür ist, dass der gcc (grob gesagt) die "vtable" zusammen mit der Definiton von virtuellen Funktionen emittiert.
    (Also insbesondere bitte beachten das das für andere Compiler nicht unbedingt gelten muss).
    ähm, jo, hmm, und wie mach ich das nun! Was meinst du genau mit der Definition?!?

    mfG
    Going to church does not make a person religious, nor does going to school make a person educated, any more than going to a garage makes a person a car.

  12. #12
    Registrierter Benutzer
    Registriert seit
    23.05.2004
    Beiträge
    592
    und wie mach ich das nun! Was meinst du genau mit der Definition?!?
    Das hier ist ne Deklaration:
    Code:
    void func();
    Und das hier ist ne Definition:
    Code:
    void func {}
    Kurz gesagt ist die Definition einer Funktion das mit dem Funktionskörper.
    Und so eine Definition musst du irgendwie in das Programm einbringen. Beispiel, das folgende funktioniert mit dem gcc nicht:
    Code:
    struct A
    {
    virtual void func();
    };
    
    int main() { A a; }
    Es funktioniert nicht, weil der gcc keine Definiton für A::func() sieht, und deshalb keine vtable anlegt.

    Folgendes würde gehen:
    Code:
    struct A
    {
    virtual void func();
    };
    
    void A::func() { }
    
    int main() { A a; }
    Die Definition von A::func() muss aber nicht unbedingt in der Übersetzungseinheit sein, in der sich auch main() befindet. Du kannst auch separat eine Datei übersetzen (ohne main funktion) und dann hinzulinken.

    Und wie Ringding schon gesagt hat, du solltest den gcc als g++ oder c++ aufrufen, u.a. weil dann die Standardbibliothek richtig hinzugelinkt wird.

  13. #13
    Registrierter Benutzer
    Registriert seit
    19.04.2003
    Beiträge
    194
    ähm ich kompiliere doch mit g++! ich weiß nicht, bin ich zu blöd für c++, oder was hat's da?!?

    mfG
    Going to church does not make a person religious, nor does going to school make a person educated, any more than going to a garage makes a person a car.

  14. #14
    Registrierter Benutzer
    Registriert seit
    23.05.2004
    Beiträge
    592
    ähm ich kompiliere doch mit g++!
    Okay! Das hatte ich bloß zur Sicherheit nochmal erwähnt.

  15. #15
    Registrierter Benutzer
    Registriert seit
    19.04.2003
    Beiträge
    194
    ok Problem hatte sich nun erledigt... Designfehler (tja bei Java ist es danke Interpreter bequemer...)!

    Im Prinzip check ich alle grundlegenden Sachen in C++, no na hab auch 1 Jahr bis jetzt Java geproggt, aber das mit den abstrakten Methoden.... dass ich da kein Objekt draus erstellen kann und Java "irgendwie" doch:
    Angenommen ich hab eine Klasse Mitarbeiter mit abstrakten Methoden und einen Constructor, wo zb Namen, etc. übergeben werden muss. Wenn ich jetzt eine Sub-Klasse erstelle und die abstrakten Methode "erstellt" und auch einen Constructor wo ich neben dem Namen noch weiter Sachen übergeben muss, dann kann ich leider nicht den Konstruktor von "Mitarbeiter" aufrufen, in Java ging das zb!
    Gibts in C++ so etwas ähnliches wie super in Java?!?

    mfG

    PS: Bisher vielen dank für die Antworten!
    Going to church does not make a person religious, nor does going to school make a person educated, any more than going to a garage makes a person a car.

Lesezeichen

Berechtigungen

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