Anzeige:
Ergebnis 1 bis 11 von 11

Thema: C++ Klassen Überladungs Problem

  1. #1
    Registrierter Benutzer Avatar von oracle2025
    Registriert seit
    18.03.2002
    Beiträge
    136

    C++ Klassen Überladungs Problem

    Warum kompiliert folgender Code nicht?
    Code:
    class A
    {
    	public:
    		virtual void X( int ) {}
    		virtual int X() { return 0; }
    };
    
    class B : public A
    {
    	public:
    		void X( int ) {}
    };
    
    
    int main()
    {
    	B b_class;
    	b_class.X();
    }
    ich kriege folgende Fehlermeldung, obwohl ich glaube dass das funktionieren müsste. Was habe ich übersehen?

    Code:
    test.cxx: In function »int main()«:
    test.cxx:21: Fehler: keine passende Funktion für Aufruf von »B::X()«
    test.cxx:13: Anmerkung: Kandidaten sind: virtual void B::X(int)
    Niemand dringt hier durch und
    gar mit der Botschaft eines Toten.
    Du aber sitzt an Deinem Fenster und
    erträumst sie Dir, wenn der Abend kommt.

  2. #2
    Registrierter Benutzer
    Registriert seit
    27.07.2000
    Beiträge
    123
    du musst mal die fehlermeldung richtig lesen und dann deinen code ;-)

    X( ) != X (int)

  3. #3
    Registrierter Benutzer Avatar von peschmae
    Registriert seit
    14.03.2002
    Ort
    Schweizland
    Beiträge
    4.549
    Das ist ihm (und mir) schon klar. Aber B ist ja von A abgeleitet, und A hat ein X();

    Zur Frage: Ich weiss es nicht, aber vom Stil her wäre das so ne typische comp.lang.c++.moderated-Frage
    Hab eben mal noch in "Design and Evolution of C++" nachgeguckt weil da so Zeugs oft noch erwähnt ist - aber dazu steht leider gar nichts.

    MfG Peschmä
    Geändert von peschmae (11-02-2006 um 16:24 Uhr)
    The greatest trick the Devil ever pulled was convincing the world he didn't exist. -- The Usual Suspects (1995)
    Hey, I feel their pain. It's irritating as hell when people act like they have rights. The great old one (2006)

  4. #4
    Registrierter Benutzer
    Registriert seit
    23.05.2004
    Beiträge
    592
    Warum kompiliert folgender Code nicht?
    void B::X(int) verdeckt die X in A. Du könntest entweder die X von A in B per using-Deklaration auch in B bekanntmachen, oder alle X in B reimplementieren. Siehe hier:
    http://www.parashift.com/c++-faq-lit....html#faq-23.9

    Ich vermute übrigens, dass du kompilierst, ohne Warnungen aktiviert zu haben. Wenn das stimmt, dann würde ich dir raten das zu ändern.

  5. #5
    Registrierter Benutzer
    Registriert seit
    27.07.2000
    Beiträge
    123
    Zitat Zitat von locus vivendi
    void B::X(int) verdeckt die X in A. Du könntest entweder die X von A in B per using-Deklaration auch in B bekanntmachen, oder alle X in B reimplementieren. Siehe hier:
    http://www.parashift.com/c++-faq-lit....html#faq-23.9

    Ich vermute übrigens, dass du kompilierst, ohne Warnungen aktiviert zu haben. Wenn das stimmt, dann würde ich dir raten das zu ändern.
    mmmhh, also ich habe das gerade mal mit der option wall compiliert. da kommen nicht mehr meldungen, die dieses problem betreffen.

    aber der link ist gut ;-) muss da nächste woche mal ein bischen tiefer reinschnuppern ..

    gruesse

    ps: ups, ich hatte nur flüchtig drüber gelesen .... und dachte, dass das übersehen wurde. das ist mir auch schon oft passiert. nun habe ich nebenbei noch was dazugelernt ,-)

  6. #6
    Registrierter Benutzer Avatar von oracle2025
    Registriert seit
    18.03.2002
    Beiträge
    136
    Zitat Zitat von locus vivendi
    Ich vermute übrigens, dass du kompilierst, ohne Warnungen aktiviert zu haben. Wenn das stimmt, dann würde ich dir raten das zu ändern.
    Hoppla,
    Niemand dringt hier durch und
    gar mit der Botschaft eines Toten.
    Du aber sitzt an Deinem Fenster und
    erträumst sie Dir, wenn der Abend kommt.

  7. #7
    Registrierter Benutzer Avatar von oracle2025
    Registriert seit
    18.03.2002
    Beiträge
    136
    Zitat Zitat von locus vivendi
    void B::X(int) verdeckt die X in A. Du könntest entweder die X von A in B per using-Deklaration auch in B bekanntmachen, oder alle X in B reimplementieren. Siehe hier:
    http://www.parashift.com/c++-faq-lit....html#faq-23.9
    Pfft, man lernt nie aus.
    Niemand dringt hier durch und
    gar mit der Botschaft eines Toten.
    Du aber sitzt an Deinem Fenster und
    erträumst sie Dir, wenn der Abend kommt.

  8. #8
    Registrierter Benutzer Avatar von panzi
    Registriert seit
    04.05.2001
    Ort
    Kottingbrunn
    Beiträge
    609
    Zitat Zitat von locus vivendi
    void B::X(int) verdeckt die X in A. Du könntest entweder die X von A in B per using-Deklaration auch in B bekanntmachen, oder alle X in B reimplementieren. Siehe hier:
    http://www.parashift.com/c++-faq-lit....html#faq-23.9

    Ich vermute übrigens, dass du kompilierst, ohne Warnungen aktiviert zu haben. Wenn das stimmt, dann würde ich dir raten das zu ändern.
    Sollte es net auch gehn das eine X in B virtual zu machen?
    Intel Core 2 Duo CPU 2.66GHz; Nvidia GeForce 8 8800 GTS; 4GB RAM; Fedora 12; KDE-testing

  9. #9
    Registrierter Benutzer
    Registriert seit
    18.03.2005
    Beiträge
    211
    Sollte es net auch gehn das eine X in B virtual zu machen?
    Nein, weil das X in B schon Virtuell ist ....

    ist eine funktion in ner basisklasse virtuell, sind alle funktionen in den abgeleiteten klassen mit gleicher Signatur (signatur != Name) auch virtuell !

    Iss nur schlechter Stil das das virtual da nich dasteht ^^

    Ciao ...

  10. #10
    Registrierter Benutzer Avatar von panzi
    Registriert seit
    04.05.2001
    Ort
    Kottingbrunn
    Beiträge
    609
    Zitat Zitat von RHBaum
    Nein, weil das X in B schon Virtuell ist ....

    ist eine funktion in ner basisklasse virtuell, sind alle funktionen in den abgeleiteten klassen mit gleicher Signatur (signatur != Name) auch virtuell !

    Iss nur schlechter Stil das das virtual da nich dasteht ^^

    Ciao ...
    aha, das wusst ich garnet.
    Intel Core 2 Duo CPU 2.66GHz; Nvidia GeForce 8 8800 GTS; 4GB RAM; Fedora 12; KDE-testing

  11. #11
    Registrierter Benutzer
    Registriert seit
    18.03.2005
    Beiträge
    211
    Ja aber auch logisch, sonst koennte man ja virtualitaet wieder rueckgaengig machen ... gewollt oder ungewollt ^^
    Bzw in vielen faellen waer es undefiniert, welche funktion genau aufgerufen werden wuerde, grad fuer Entwickler von Frameworks ein Horrorszenario ^^

    Deswegen auch die Geschichte mit dem verdecken ....
    das nicht gleich nach der Signatur, sondern erst nur nach dem Namen in der aktuellen klasse gesucht wird und versucht wird darauf zu matchen, hat natuerlich auch seine tieferen Gruende !

    Stell Dir vor du hasst nen framework, da leitest von ner Klasse C ab, C ist auch dafuer vorgesehen und gut dokumentiert. Das C intern von A und B ableitet steht nirgendswo weil das implementationsdetails sind und dich nich intressieren sollt ....

    Du willst aber ne Methode C::X(int) verwenden ... also :

    char test = 5;
    C c;
    c.X(test);

    sieht alles ok aus ... soweit.

    Nur ein problem, dein parameter ist char, erwartet wird int, du verlaesst dich auf die impliziete Konversion. Iss ja auch zulaessig ....

    Aber was wuerde passieren, wenn eine der Basisklassen A oder B eine funktion (die muss nich mal virtuell sein) X(char) haben ?
    statt C::X(int) wuerde B::X(char) aufgerufen, von der du nix weisst und die sicher ned macht was du willst .
    Es hilft auch nix, da B::X(char) protected zu machen, weil der eintrag wuerde trotzdem generiert werden, er wuerde trotzdem auf die funktion matchen du wuerdest nur nen Permission-Fehler bekommen, weil es protected waer.

    mit char und int ist das aber noch recht uebersichtlich, nun stell dir aber mal das Szenario vor mit dem Wissen, das jeder Konstruktur mit einem Argument wie eine impliziete Konversion wirkt ....

    Ciao ...

Lesezeichen

Berechtigungen

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