uint8_t und cout



  • Hallo nochmal,

    ich habe die Funktion nun so abgeändert:

    ostream & operator<<(ostream& s, const ASTTerm& t) {
    
        switch (t.getType()) {
            case DSM_TERM_UNARY:
                return s << "DSM_TERM_UNARY "
                        << (int) t.getVariableNumber();
            [...]
        }//End switch
    }//End operator<<
    

    Wenn ich in main folgendes proibiere:

    ASTTerm term1;
    cout << term1 << endl;
    

    Erhalte ich als Compilerfehler:

    source/qep-creation.cpp:113: undefined reference to `ast::operator<<(std::basic_ostream<char, std::char_traits<char> >&, ast::ASTTerm const&)'
    

    Ich raffe es nicht.
    Uwe



  • Definier die Überladung global. Dann sollte das klappen..



  • Hallo drakon,

    also wenn ich ne Methode als friend deklariere, dann ist sie doch automatisch quasi global, oder? Aber selbst wenn ich die Dekleration aus der Klasse rausziehe ändert sich nichts. Was mich wundert ist, trotz friend kann ich in der Methodenimplementierung nicht auf private Elemente des Terms zugreifen. Das heißt doch, dass meine Dekleration/Implementierung irgendwie falsch ist?! Hier nochmal die beiden Dateiauszüge:
    ASTTerm.h

    #ifndef _ASTTERM_H
    #define	_ASTTERM_H
    
    #include "../DSMQL.h"
    #include <stdlib.h>
    #include <stdint.h>
    #include <ostream>
    
    using std::ostream;
    
    namespace ast{
    
    class ASTTerm {
    public:
    
        ASTTerm();
        ASTTerm(uint8_t vn);
        ~ASTTerm();
        virtual TermType getType() const;
        void setType(TermType t);
        [...]
        friend ostream& operator<<(ostream&, const ASTTerm&);
        [...]
    };
    }//End namespace
    #endif	/* _ASTTERM_H */
    

    Und die Implementierung in ASTTerm.cpp:

    #include "astterm.h"
    
    using namespace ast;
    [...]
    ostream& operator<<(ostream& s, const ASTTerm& t) {
    
        return s << t.getType; //geht
    //  return s << t.type //geht nicht, trotz friend
    }//End operator<<
    

    Aufrufen verusche ich es per:

    #include <stdlib.h>
    #include <iostream>
    #include "ast/astterm.h"
    
    using ast::ASTTerm;
    
    int main(int argc, char** argv) {
    ASTTerm term1;
    std::cout << term1;
    return(0};
    }//End main
    

    Was folgenden Fehler gibt:

    source/qep-creation.cpp:113: undefined reference to `ast::operator<<(std::basic_ostream<char, std::char_traits<char> >&, ast::ASTTerm const&)'
    

    Uwe



  • ostream& operator<<(ostream& s, const ASTTerm& t)
    

    ➡

    ostream& ASTTerm::operator<<(ostream& s, const ASTTerm& t)
    

    uwerothfeld schrieb:

    return s << t.type //geht nicht, trotz friend

    Die als "friend" deklarierte Operator-Funktion ist quasi "static", deshalb gibt's da kein "this" und kein implizites Zugreifen auf Member-Variablen.



  • Hallo Badestrand,

    also ich glaube da irrst du, denn laut hier ist ein Ausgabeoperator "<<" nie eine Memberfunktion. Daher kann ASTTerm:operator<< auch nicht gehen und führt zu:

    source/ast/astterm.cpp:246: Fehler: »std::ostream& ast::ASTTerm::operator<<(std::ostream&, const ast::ASTTerm&)« muss genau ein Argument nehmen
    

    außerdem ist this != friend. Ich will ja nicht this->type machen, sondern t.type, was laut obigen Link gehen sollte. 😞

    Es kann doch nicht so schwer sein, dass zum laufen zu bringen. Ich bin gefrustet.

    Uwe



  • uwerothfeld schrieb:

    also ich glaube da irrst du, denn laut hier ist ein Ausgabeoperator "<<" nie eine Memberfunktion. Daher kann ASTTerm:operator<< auch nicht gehen

    Höh? Klar, du deklarierst das Ding ja auch in der Klasse "ASTTerm". Dann musst du logischerweise auch ein "ASTTerm::" bei der Definition davorhängen. Mach das und alles funktioniert so, wie du es willst 😉

    edit: Also so:

    // cpp-Datei:
    class ASTTerm {
        [...]
        friend ostream& operator<<( ostream&, const ASTTerm& );
        [...]
    };
    
    // Header-Datei:
    ostream& ASTTerm::operator<<(ostream& s, const ASTTerm& t)
    {
        return s << t.type //geht, wegen friend
    }
    


  • Hallo Badestrand,

    ne leider eben nicht, da dann der Compiler dies sagt:

    source/ast/astterm.cpp:254: Fehler: »std::ostream& ast::ASTTerm::operator<<(std::ostream&, const ast::ASTTerm&)« muss genau ein Argument nehmen
    

    Ich weeß nicht mehr weiter 😞
    Uwe



  • Hab's eben mal ausprobiert, da hatte ich das völlig falsch in Erinnerung 😕 Das "ASTTerm::" ist anscheinend wirklich falsch, hier mein funktionierender Testcode:

    #include <iostream>
    
    namespace ast
    {
    	class ASTTerm
    	{
    		public:
    			friend std::ostream& operator<<( std::ostream& o, const ASTTerm& );
    
    		private:
    			int i;
    	};
    
    	std::ostream& operator<<( std::ostream& o, const ASTTerm& me )
    	{
    		return o << me.i;
    	}
    }
    

    Welchen Compiler nutzt du denn? (Btw: "using namespace" in Headern ist zurecht verpönt.)


  • Administrator

    @Badestrand,
    Du meinst wohl so:

    // Header-Datei: // <--
    class ASTTerm { 
        [...] 
        friend ostream& operator<<( ostream&, const ASTTerm& ); 
        [...] 
    }; 
    
    // cpp-Datei: // <--
    ostream& operator<<(ostream& s, const ASTTerm& t) // <--
    { 
        return s << t.type //geht, wegen friend 
    }
    

    Grüssli



  • Dravere schrieb:

    @Badestrand,
    Du meinst wohl so: [...]

    Leider zwei Sekunden zu spät :p (Außer für das Verwechseln von cpp- und Header-Datei, ohje ohje)


  • Administrator

    Badestrand schrieb:

    Dravere schrieb:

    @Badestrand,
    Du meinst wohl so: [...]

    Leider zwei Sekunden zu spät :p (Außer für das Verwechseln von cpp- und Header-Datei, ohje ohje)

    Da scheint gewisses Wissen langsam einzurosten 🙂
    Vielleicht noch als Ergänzung:
    http://www.cplusplus.com/doc/tutorial/inheritance.html
    http://tutorial.schornboeck.net/operatoren_ueberladung2.htm

    Grüssli 🙂



  • Hallo Badestrand und Dravere,

    also ich nutze NetBeans 6.5.1. Dort ist als C++ Compiler /usr/lib/ccache/gcc, definiert, was ein:

    g++ (GCC) 4.3.2 20081105 (Red Hat 4.3.2-7)
    Copyright (C) 2008 Free Software Foundation, Inc.
    Dies ist freie Software; die Kopierbedingungen stehen in den Quellen. Es
    gibt KEINE Garantie; auch nicht für MARKTGÄNGIGKEIT oder FÜR SPEZIELLE ZWECKE.
    

    ist. Das ganze auf einem Fedora 10. Ich habe alles rüberkopiert, wie du es angegeben hast, aber das Problem bleibt. Gleiche Fehlermeldung und immernoch fehlender Zugriff auf die Member. Komisches Ding.

    Uwe


  • Administrator

    1. Zeig es mal an einem kleinen und funktionierenden Beispielquellcode, was du machst.
    2. Hast du die Tutoriallinks durchgelesen?

    Grüssli



  • Hallo ihr beide,

    gute Idee, mit dem Minibsp. Warum kann man hier nix anhängen?? Mh. Egal.

    Datei ASTTerm.h:

    /**
     * File:   astterm.h
     */
    #ifndef _ASTTERM_H
    #define	_ASTTERM_H
    
    #include <stdlib.h>
    #include <stdint.h>
    #include <ostream>
    
    namespace ast{
    
    class ASTTerm {
    public:
        ASTTerm(int vn);
        friend std::ostream& operator<<( std::ostream& s, const ASTTerm& t);
        int getI() const;
    private:
        int i;
    };
    }//End namespace
    #endif	/* _ASTTERM_H */
    

    Datei ASTTerm.cpp:

    /*
     * File:   astterm.cpp
     */
    #include "ASTTerm.h"
    
    using namespace ast;
    
    ASTTerm::ASTTerm(int vn) {
        this->i = vn;
    }//End ASTTerm
    
    int ASTTerm::getI() const {
        return this->i;
    }//End getI
    
    std::ostream& operator<<( std::ostream& s, const ASTTerm& t) {
    
        //return s << t.i; //geht nicht trotz friend
        return s << t.getI(); //geht
    
    }//End operator<<
    

    Die main:

    /* 
     * File:   main.cpp
     */
    
    #include <stdlib.h>
    #include <iostream>
    #include "ast/ASTTerm.h"
    
    int main(int argc, char** argv) {
    
        ast::ASTTerm term(1);
        std::cout<<term <<std::endl;  //geht nicht
        //Fehler von Compiler
        ///source/main.cpp:20: undefined reference to `ast::operator<<(std::basic_ostream<char, std::char_traits<char> >&, ast::ASTTerm const&)'
    
        return (EXIT_SUCCESS);
    }
    

    Die Fehlermeldung vom Compiler ist ja bekannt. 🙂 Die Tutorials habe ich durchgelesen. Ich habe auch die verschiedenen Stellungen von const in der Signatur getestet, alles das gleiche ....

    Uwe


  • Administrator

    Hast du auch das Objectfile, welches aus astterm.cpp erzeugt wird, bei der Kompilierung von main.cpp dazugefügt?

    Im übrigen sind die folgenden 2 Header keine Standard C++ Header:
    `#include <stdlib.h>

    #include <stdint.h>`

    Das sind C Header. Für <stdlib.h> gibt es in C++ den <cstdlib> , wo dann auch alle Funktionen in Namensraum std sind. Für <stdint.h> gibt es in C++ keinen entsprechenden Header, da dieser erst in C99 dazukam. Man sollte im allgemeinen eher auf C++ Funktionen in C++ zurückgreifen. Die C Funktionen wurden nunmal nicht für C++ geschaffen.

    Grüssli



  • Hi,

    Dravere schrieb:

    Hast du auch das Objectfile, welches aus astterm.cpp erzeugt wird, bei der Kompilierung von main.cpp dazugefügt?

    Gute Frage. Hab in NetBeans einfach Compile gedrückt. Mh. Ich gehe eingentlich mal davon aus, dass dies das Makefile berücksichtigt. Wenn ich es über Kommandozeile compiliere, ergibt sich:

    gcc ast/ASTTerm.cpp main.cpp -o out.a
    /tmp/cc2yuDFt.o: In function `operator<<(std::basic_ostream<char, std::char_traits<char> >&, ast::ASTTerm const&)':
    ASTTerm.cpp:(.text+0x42): undefined reference to `std::basic_ostream<char, std::char_traits<char> >::operator<<(int)'
    /tmp/cc2yuDFt.o:(.eh_frame+0x11): undefined reference to `__gxx_personality_v0'
    /tmp/ccWDxdeD.o: In function `__static_initialization_and_destruction_0(int, int)':
    main.cpp:(.text+0x1d): undefined reference to `std::ios_base::Init::Init()'
    main.cpp:(.text+0x22): undefined reference to `std::ios_base::Init::~Init()'
    /tmp/ccWDxdeD.o: In function `main':
    main.cpp:(.text+0x8a): undefined reference to `std::cout'
    main.cpp:(.text+0x8f): undefined reference to `ast::operator<<(std::basic_ostream<char, std::char_traits<char> >&, ast::ASTTerm const&)'
    main.cpp:(.text+0x97): undefined reference to `std::basic_ostream<char, std::char_traits<char> >& std::endl<char, std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&)'
    main.cpp:(.text+0x9f): undefined reference to `std::basic_ostream<char, std::char_traits<char> >::operator<<(std::basic_ostream<char, std::char_traits<char> >& (*)(std::basic_ostream<char, std::char_traits<char> >&))'
    /tmp/ccWDxdeD.o:(.eh_frame+0x11): undefined reference to `__gxx_personality_v0'
    collect2: ld gab 1 als Ende-Status zurück
    

    Was doch in etwa das gleiche ist. Oder?

    Bezüglich der Header danke für den Tipp. Also stdint.h benötige ich nur für uint8_t, unint16_t, ... Typen innerhalb meines Projektes (Vorgabe 😞 ). DAs mit stdlib werde ich gleich ändern.

    Uwe



  • Hatte ich vorhin gar nicht gesehen: Du musst die Definition von std::ostream& operator<<( std::ostream& s, const ASTTerm& t) auch innerhalb namespace ast { .. } einpacken 🙂



  • Hi badestrand,

    ist es doch? Siehe mein Minibeispiel. Oder irre ich da?

    Uwe


  • Administrator

    uwerothfeld schrieb:

    ist es doch? Siehe mein Minibeispiel. Oder irre ich da?

    Nein! Badestrand hat recht, habe es auch vollkommen übersehen. Du machst in der *.cpp ein using namespace ast; , was aber nicht das gleiche ist, wie wenn du alles in den Rumpf von namespace ast setzen würdest.

    Am besten schreibst du die *.cpp auf die folgende Art und Weise:

    /*
     * File:   astterm.cpp
     */
    #include "ASTTerm.h"
    
    namespace ast {
    
    ASTTerm::ASTTerm(int vn) {
        this->i = vn;
    }//End ASTTerm
    
    int ASTTerm::getI() const {
        return this->i;
    }//End getI
    
    std::ostream& operator<<( std::ostream& s, const ASTTerm& t) {
    
        //return s << t.i; //geht nicht trotz friend
        return s << t.getI(); //geht
    
    }//End operator<<
    
    } // ast
    

    Grüssli



  • Hi Jungs,

    Es geht!!!!! 👍 Ist ja der WAHNSINN!!! Geil. Ich bin begeistert. Vielen, vielen, vielen Dank für Eure Hilfe. Man, da wäre ich nie drauf gekommen. Super. Es geht wie ne eins. Toll. Vielen Dank für Eure Hilfe.

    Uwe, der vor Freude im Viereck springt.

    Thread *close* sozusagen!!! 🙂


Anmelden zum Antworten