C++ operator



  • Hallo leute ich habe ein kleines promblem :

    Header:

    #ifndef CTIP_H_
    #define CTIP_H_
    #include <iostream>
    #include<string>
    using namespace std;
    
    class CTip {
    
    private:
    	 unsigned short m_numbers[6];
         unsigned short m_countNumbers = 0;
    
    public:
         CTip();
         bool addNumber( unsigned short number );
         bool isValid();
         unsigned short operator*(CTip& other);
    
    	friend std::ostream& operator <<(std::ostream& out, CTip& const tip);
    
    };
    std::ostream& operator <<(std::ostream& out, CTip& const tip);
    
    #endif /* CTIP_H_ */
    

    cpp:

    #include <iostream>
    #include<string>
    using namespace std;
    
    CTip::CTip {
    	m_numbers = new unsigned short[6];
    	m_countNumbers = 0;
    
    }
    
    std::ostream& operator <<(std::ostream& out, CTip& tip)
    {
    for(int i = 0; i < 6; i++)
    
            out << m_numbers[i] << " " ;
    return out;
    }
    

    Ich verstehe zu erst einmal nicht warum mir folgende fehler angezeigt werden?

    Description Resource Path Location Type
    Type 'CTip' could not be resolved CTip.cpp / line 22 Semantic Error
    Symbol 'm_numbers' could not be resolved CTip.cpp /WS2013 line 26 Semantic Error
    Type 'namespace' could not be resolved CTip.h / line 12 Semantic Error
    Type 'CTip' could not be resolved main.cpp / line 11 Semantic Error

    Und noch eine kleine frage zu einer Aufgabenstellung:

    Legen Sie in main.cpp den Tipp myTip an und geben Sie ihn mit dem operator<< auf der
    Konsole aus.

    Kann ich so den Operatoor in der main ausgeben?

    #include<iostream>
    using namespace std;
    
    int main(){
    	CTip myTip;
    
    	out << myTip << endl;
    
    }
    


  • Wozu ist deiner Meinung nach der Header da?


  • Mod

    #include "ctip.h" fehlt vermutlich.



  • Leider scheinen die Fehler immer noch nict weg zu gehen .

    Hat das irgendwas damit zu tun ,dass ich Linux benutze?

    #ifndef CTIP_H_
    #define CTIP_H_
    #include <iostream>
    #include<string>
    using namespace std;
    
    class CTip {
    
    private:
    	 unsigned short m_numbers[6];
         unsigned short m_countNumbers = 0;
    
    public:
         CTip();
         bool addNumber( unsigned short number );
         bool isValid();
         unsigned short operator*(CTip& other);
    
    	friend std::ostream& operator <<(std::ostream& out, CTip& const tip);
    
    };
    std::ostream& operator <<(std::ostream& out, CTip& const tip);
    
    #endif /* CTIP_H_ */
    
    #include <iostream>
    #include <string>
    #include "CTip.h"
    using namespace std;
    
    CTip::CTip {
    	m_numbers = new unsigned short[6];
    	m_countNumbers = 0;
    
    }
    
    std::ostream& operator <<(std::ostream& out, CTip& tip)
    {
    for(int i = 0; i < 6; i++)
    
            out << m_numbers[i] << " " ;
    return out;
    }
    
    /*
     * main.cpp
     *
     *  Created on: Mar 1, 2014
     *      Author: vaio
     */
    #include<iostream>
    #include"CTip.h"
    using namespace std;
    
    int main(){
    	CTip myTip;
    
    	out << myTip << endl;
    
    }
    

    Ist eigentlich meine operator Ausgabe richtig?



  • Born15 schrieb:

    CTip::CTip {

    Da fehlen Klammern.

    Und der Operator ist kein Member der Klasse. Du hast also keinen direkten Zugriff auf m_numbers, du musst schon die CTip-Instanz benutzen, die als Argument reinkommt.



  • Die fehler scheinen immer noch nicht weg zu gehen:

    #include <iostream>
    #include <string>
    #include "CTip.h"
    using namespace std;
    
    CTip::CTip() {
    	m_numbers = new unsigned short[6];
    	m_countNumbers = 0;
    
    }
    
    std::ostream& operator <<(std::ostream& out, CTip& tip)
    {
    for(int i = 0; i < 6; i++)
    
            out << CTip.m_numbers[i] << " " ;
    return out;
    }
    

    Jetzt diese Fehler:
    Description Resource Path Location Type
    Type 'CTip' could not be resolved CTip.cpp /W line 23 Semantic Error
    Symbol 'out' could not be resolved main.cpp / line 14 Semantic Error
    Invalid overload of 'endl' main.cpp / line 14 Semantic Error
    Type 'namespace' could not be resolved CTip.h / line 12 Semantic Error
    Type 'CTip' could not be resolved main.cpp /line 12 Semantic Error
    Symbol 'CTip' could not be resolved CTip.cpp / line 27 Semantic Error
    Field 'm_numbers' could not be resolved CTip.cpp / line 27 Semantic Error
    Member declaration not found CTip.cpp /W line 13 Semantic Error

    Irgendwas stimmt bei meiner operator ausgabe nicht?

    Ist irgendwo eine internet seite ,wo das mit der operator Ausgabe gut erklärt wird?



  • Zeig doch mal die Fehlermeldungen des Compilers. Diese da stammen offenbar von einem Tool für statische Code-Analyse.



  • Born15 schrieb:

    ...

    Da sind noch viele Fehler/Unschönheiten.

    • Bitte: Beim Posten im Forum die Leerzeilen reduzieren (möglichst auch unnötige Kommentare entfernen).
    • Unschönheit: Uneinheitlich eingerückt.
    • Fehler: new verwendet man nur bei Zeigern. Besser wäre allgemein auf C-Arrays zu verzichten und die C++ Alternativen (wie vector oder array) zu nutzen (Und mit Zeigern müsstest du dich auch um den Zuweisungsoperator und Kopierkonstruktor kümmern).
    • Fehler: Fehlende Klammern "()" hinter dem Konstruktor in der Sourcedatei.
    • Große Unschönheit: using namespace im Headern verwendet (Sollte man niemals tun)
    • Fehler: Was soll bitte "out" in deiner main-Funktion sein? cout wäre wohl das gewünschte.
    • Fehler: Für den Operator "operator*", und mehrere Methoden fehlt die Definition (Sind zwar im Header deklariert, aber nicht im Source implementiert).
    • Codestil: Was soll das "C" vor der Klasse, bist du ein Anhänger von ungarischer Notation (bei anderen Sachen Fehlen solche Präfixe aber zum Glück). Über das "m_" lässt sich streiten, kann man aber auch machen.
    • Unschönheit: Initialisierungen von Membervariablen sollte man in der Initialisierungsliste machen (Du machst eine nachträgliche Zuweisung, die initialisierung ist da bereits abgeschlossen).
    • Unschönheit: Dein m_countNumbers wird bislang nicht verwendet.
    • Fehler: Du greifst auf eine Membervariable innerhalb des Operators zu, ohne die Instanz anzugeben. Der Operator ist aber keine Methode der Klasse. Dort gehört ein "tip.m_numbers[i]" hin.

    Born15 schrieb:

    Hat das irgendwas damit zu tun ,dass ich Linux benutze?

    Nein.



  • Mittlerweile habe ich die Fehler beseitigt und bei dieser Aufgabenstellung probleme:
    Implementieren Sie die Methode addNumber(). Sie fügt eine neue Zahl an der nächsten
    freien Position zum Tipp hinzu und liefert true. Kann die Zahl nicht hinzugefügt werden,
    ohne eine der Zusicherungen zu verletzen, bleibt der Tipp unverändert und die Methode
    liefert false

    Irgendwas habe ich beim 1 teil in meiner methode add number falsch gemacht.
    Habt ihr paar tips für mich?

    #ifndef CTIP_H_
    #define CTIP_H_
    #include <iostream>
    #include<string>
    using namespace std;
    
    class CTip {
    
    private:
    	 unsigned short m_numbers[6];
         unsigned short m_countNumbers = 0;
    
    public:
         CTip();
         bool addNumber( unsigned short number );
         bool isValid();
         unsigned short operator*(CTip& other);
    
    	friend std::ostream& operator <<(std::ostream& out, CTip& const tip);
    
    };
    std::ostream& operator <<(std::ostream& out, CTip& const tip);
    
    #endif /* CTIP_H_ */
    
    /*
     * CTip.cpp
     *
     *  
     *      
     */
    
    #include <iostream>
    #include <string>
    #include "CTip.h"
    using namespace std;
    
    CTip::CTip() {
    	m_numbers = new unsigned short[6];
    	m_countNumbers = 0;
    
    }
    
    std::ostream& operator <<(std::ostream& out, CTip& tip)
    {
    for(int i = 0; i < 6; i++)
    
            out << tip.m_numbers[i] << " " ;
    return out;
    }
    CTip:: bool addNumber(){
    	for(int i = 0; i<=6; i++){
    
    		 m_numbers =  unsigned short[i+1];
    
    		return true;
    		}
    
    }
    


  • Nein, du hast deine Fehler noch nicht beseitigt. Würde mich wundern wenn irgendein Compiler dein Programm fehlerfrei schlucken würde (und wenn, ist die Warnstufe viel zu niedrig eingestellt).

    Schau dir beispielsweise meinen 3ten Punkt (den ersten Fehler an), der ist noch immer enthalten. Die Initialisierung mit new ist weiterhin hier ein Fehler (Du verwendest keinen Zeiger, sondern ein normales Array - dem weißt man keinen dynamischen Speicher zu).

    Womit lernst du C++? Egal mit was: Entweder ist deine Quelle sehr schlecht, oder du versuchst schneller zu sein, als dir gut tut...



  • Wie erstellt man den genau einen dynamischen speicher mit array genau?

    Kannst du mir das erklären?



  • Born15 schrieb:

    Wie erstellt man den genau einen dynamischen speicher mit array genau?

    Kannst du mir das erklären?

    Gegenfrage: Wozu überhaupt dynamischen Speicher an dieser Stelle.

    Ansonsten mit einem Zeiger als Member der Klasse (unsigned int* m_numbers). Nur musst du dann u.a. auch einen Destruktor, Zuweisungsoperator und Kopierkonstruktor implementieren um diesen richtig zu behandeln. Besser wäre gleich die Verwendung von std::vector<unsigned int> und der Verzicht auf New...

    Und noch viel besser wäre die Nutzung eines guten C++ Einstiegbuches um zumindest die Grundlagen zu verstehen. Tutorials und die Wolf-Bücher sind ungeeignet...



  • In der Aufgabe müssen wir leider keinen destruktor und copy Konstruktor benutzen.

    Kannst du mir nicht kurz erklären wie ich den dynamischen Speicher anlegen kann. Ich will das gerne lernen.



  • Ist in der Aufgabenstellung von dynamischen Speicher die Rede? Wenn nicht lasse es aktuell außen vor. Und nein, das Forum ist nicht da jemanden detailiert etwas zu lehren, sondern auf konkrete Fragen Hilfe zu geben.

    Aber ich versuche es in Kürze:

    Dynamischer Speicher liegt auf dem Heap und wird über einen Zeiger (der die konkrete Adresse beinhaltet) angesprochen. Im einfachen Fall wie folgt:

    int * zeiger = new int(4);
    

    Hier handelt es sich um einen int-Zeiger, sprich einer Variable die eine Speicheradresse beinhaltet, die auf einen dynamisch erzeugten int-Wert auf dem Heap verweist. In diesem Fall steht in dem Speicherbereich auf dem Heap eine 4, und in zeiger die Adresse auf diesen Speicherbereich (Kann man sich wie eine Hausnummer auf einer sehr langen Straße vorstellen, in dem Haus steht dann der Wert).

    Problem bei dynamischen Speicher: Wenn der Zeiger aus dem Gültigkeitsbereich gelangt, wird nur der Zeiger, nicht der Speicherbereich auf den dieser zeigt, freigegeben. Man muss den Speicher mittels delete freigeben.

    delete zeiger; // Gibt den Speicherbereich frei, auf den zeiger verweist.
    

    Falls in der Aufgabenstellung zwar dynamischer Speicher gefordert wird, aber kein Destruktor zum aufräumen vorgesehen ist, ist die Aufgabe Müll - oder man setzt von dir bereits die Kenntnisse voraus das du diesen dennoch schreibst.

    Dynamische Arrays werden ähnlich erzeugt:

    int * zeiger = new int[6];
    

    Dieses mal zeigt der zeiger auf das erste Element eines (noch uninitialisierten) int-Arrays, über zzeiger[0] sprichst du den Inhalt des ersten Elementes an.

    Beim Freigeben ist hierbei aber ein anderer delete-Befehl nötig, delete[].

    delete[] zeiger; // Gibt das Array frei.
    

    Nun zu der nächsten Problematik: Sobald du besitzende Zeiger verwendest, musst du immer auch den Zuweisungsoperator und Kopierkonstruktor implementieren, oder diese explizit unterbinden (Regel der Drei).

    Den wenn du beispielsweise dein Objekt kopierst, und du diese nicht implementierst, wird nur die Speicheradresse kopiert. Sprich: Beide Objekte verwenden den gleichen Speicher. Und wenn dann der Speicher von einem Objekt freigegeben wird, greift das andere Objekt ins leere (Das erzeugt ein undefiniertes Verhalten oder eine Zugriffsverletzung).

    Ist dies eine Schulaufgabe, oder woher stammt die Aufgabe?



  • Danke für die schöne Erklärung asc.

    Ich hab es jetzt mal mit Copy Konstruktor usw probiert.

    Hier mein code .Ein wenig meckern tut der Compiler noch.

    Vielleicht könnt ihr mir helfen.

    neue Header:

    #ifndef CTIP_H_
    #define CTIP_H_
    #include <iostream>
    #include<string>
    using namespace std;
    
    class CTip {
    
    private:
    	 unsigned short m_numbers[6];
         unsigned short m_countNumbers = 0;
    
    public:
         CTip();
         ~CTip();
         CTip(CTip& origin);
         bool addNumber( unsigned short number );
         bool isValid();
         unsigned short operator*(CTip& other);
    
    	friend std::ostream& operator <<(std::ostream& out, CTip& const tip);
    
    };
    std::ostream& operator <<(std::ostream& out, CTip& const tip);
    
    #endif /* CTIP_H_ */
    

    Ich hoffe der Copy Konstruktor ist richtig, da war ich mir nicht 100% sicher.

    #include <iostream>
    #include <string>
    #include "CTip.h"
    using namespace std;
    
    CTip::CTip() {
    	unsigned int*m_numbers =  unsigned short[6];
    	m_countNumbers = 0;
    
    }
    ~CTip::CTip(){
    
    	delete[] m_numbers;
    
    }
    CTip::CTip(CTip& origin){
    	unsigned int*origin_m_numbers =  unsigned short[6];
    		origin_m_countNumbers = 0;
    
    }
    
    std::ostream& operator <<(std::ostream& out, CTip& tip)
    {
    for(int i = 0; i < 6; i++)
    
            out << tip.m_numbers[i] << " " ;
    return out;
    }
    
    bool CTip::addNumber(unsigned short numberToAdd){
        if (m_countNumbers >= 6){ //kein PLatz mehr zum Anhängen
            return false; //liefere Fehler zurück
    
        }
    	if(m_countNumbers <= 6){
        m_numbers[m_countNumbers++] = numberToAdd;
        return true; //"alles OK" aus Antwort
    
    	}
    
    }
    
    CTip::bool isValid(){
    	if(m_countNumbers ==6){
    
    		return true;
    	}
    
    }
    

    Fehlermeldungen:

    Description Resource Path Location Type
    Member declaration not found CTip.cpp /line 28 Semantic Error
    Symbol 'origin_m_countNumbers' could not be resolved CTip.cpp line 30 Semantic Error
    line 12 Semantic Error
    No return, in function returning non-void CTip.cpp / line 43 Code Analysis Problem

    Ich hoffe ihr könnt mir helfen. 🙂



  • Born15 schrieb:

    Danke für die schöne Erklärung asc.

    Wäre noch schöner wenn du sie wirklich verstehen würdest.

    Born15 schrieb:

    Hier mein code .

    ... der leider noch immer genauso schlecht wie vorher ist. Lies ein Einstiegsbuch (In deinem Fall würde ich zu "C++ from zero to hero" raten, die anderen dürften dir vermutlich noch zu schwer sein).

    Born15 schrieb:

    Ein wenig meckern tut der Compiler noch.

    Ganz ehrlich: Ich an stelle des Compilers würde richtig stark meckern. Vermutlich ist die Warnstufe viel zu niedrig (Um welchen Compiler handelt es sich?).

    #ifndef CTIP_H_
    #define CTIP_H_
    #include <iostream>
    #include <string>   // Einheitlich einrücken
    // using namespace std; - NIEMALS IM HEADER!!!
    
    // Du solltest deine IDE so einstellen, das Tabulatoren durch Leerzeichen
    // ersetzt werden, dann sieht der Code auch im Forum angenehm aus.
    class CTip {
    private:
        // Was nun? Dynamische Speicherverwaltung oder nicht?
        // Dynamische Speicherverwaltung => Hier ein Zeiger nötig, kein Array!
        // unsigned short m_numbers[6];
        unsigned short * m_numbers; // <-- Du wolltest dynamische Speicherverwaltung
        unsigned short m_countNumbers = 0;
    
    public:
         CTip();
         // Sobald mindestens eins der folgenden nötig ist (und mit dynamischer
         // Speicherveraltung sind diese nötig)...:
         // - Destruktor
         // - Kopierkonstruktor
         // - Zuweisungsoperator
         // MÜSSEN auch die anderen geschrieben werden.
         ~CTip();
         CTip(CTip& origin);
         CTip& operator=(CTip& origin); // Zuweisungsoperator
    
         bool addNumber(unsigned short number); // Einheitliche Einrückung
         bool isValid();
         unsigned short operator*(CTip& other);
    
         friend std::ostream& operator <<(std::ostream& out, CTip& const tip);
    };
    
    std::ostream& operator <<(std::ostream& out, CTip& const tip);
    
    #endif /* CTIP_H_ */
    

    Born15 schrieb:

    neue Header:
    Ich hoffe der Copy Konstruktor ist richtig, da war ich mir nicht 100% sicher.

    Nicht einmal ansatzweise.

    #include <iostream>
    #include <string>
    #include "CTip.h"
    using namespace std;
    
    CTip::CTip()
    :   m_numbers(new unsigned short[6]), // <-- Initialisierungsliste
        countNumbers(0)
    {
        // <-- Hier wurden bereits die Member initialisiert, alles hier drin
        //     ist eine _nachträgliche_ Zuweisung.
        // Lokale Variable: unsigned int * m_numbers = unsigned short[6];
        // Wenn schon:      m_numbers = unsigned short[6];
        // m_countNumbers = 0;
    }
    
    ~CTip::CTip(){
        delete[] m_numbers;
    }
    
    CTip::CTip(CTip& origin)
    :   m_numbers(new unsigned short[6]), // <-- Initialisierungsliste
        countNumbers(0)
    {
        // 1. Das neue Objekt benötigt einen eigenen Speicherbereich
        //    (in Initialisierungsliste erzeugt)
        // 2. Werte aus dem Ursprungsarray sind zu kopieren.
        for(unsigned pos=0; pos<6; ++pos)
            m_numbers[pos] = origin.m_numbers[pos]
    
        // Was soll das werden?
        // Lokale Variable, unsinnige Einrückung: unsigned int*origin_m_numbers =  unsigned short[6];
        // Gibts nicht: origin_m_countNumbers = 0;
        // Meinst du: origin.m_countNumbers?
    }
    
    CTip& CTip::operator=(CTip& origin)
    {
        // Hier existieren die Member bereits, doch die Werte müssen übertragen
        // werden (NICHT DEN ZEIGER KOPIEREN, SONDERN DEN INHALT!).
        // 2. Werte aus dem Ursprungsarray sind zu übertragen.
        for(unsigned pos=0; pos<6; ++pos)
            m_numbers[pos] = origin.m_numbers[pos]
        countNumbers = origin.m_countNumbers;
    
        return *this; // Sich selbst zurückgeben
    }
    
    std::ostream& operator<<(std::ostream& out, CTip& tip)
    {
        // Sauber und einheitlich einrücken!
        for(int i = 0; i < 6; i++)
            out << tip.m_numbers[i] << " ";
        return out;
    }
    
    bool CTip::addNumber(unsigned short numberToAdd){
        if(m_countNumbers >= 6){
            //kein Platz mehr zum Anhängen
            return false; //liefere Fehler zurück
        }
    
        if(m_countNumbers <= 6){
            m_numbers[m_countNumbers++] = numberToAdd;
            return true; //"alles OK" aus Antwort
        }
    }
    
    CTip::bool isValid(){
        if(m_countNumbers ==6){
            return true;
        }
        // <-- Und was gibst du sonst zurück?
    }
    

    Dies ist meine letzte Hilfe, da du keinerlei Lerneffekt zeigst, vorher genannte Fehler weder beachtest noch hinterfragst... Zudem ist meine Lösungshilfe für dich ohnehin wertlos, ich sehe das du mit der restlichen Aufgabenstellung ohnehin nicht klar kommen wirst.

    Wenn du wirklich Hilfe willst:
    a) Beachte den Thead: Wichtig: Du brauchst Hilfe?
    b) Antworte auch auf Rückfragen.
    c) Stelle _konkrete_ Fragen.

    Ich für meinen Teil klinke mich hier aus.


Log in to reply