Includes und aufsplitten in .cpp und .h



  • Das halte ich für mehr als unwahrscheinlich. Wie sieht denn deine Zeile 9 jetzt aus, nachdem du sie geändert hast?

    Und (hat nix mit dem Problem zu tun) du benutzt "const" scheinbar irgendwie. Warum ist summand1 ein

    const Zahl* const
    

    , aber summand2 ein

    const Zahl*
    

    ? Analog beim Multiplizieren. Komisches Design.



  • Ich habe es getestet -> Der selbe Fehler

    Hier nochmal das UML-Klassendiagramm und der ganze Code aller Dateien. Ich weiß, dass das viel ist, aber vlt. kann es ja hilfreich sein.

    UML-Klassendiagramm

    https://drive.google.com/file/d/0B8p3-t4oD8EiN3J1VC1RMm5ZSXM/view?usp=sharing

    main.cpp

    #include <iostream>
    #include <sstream>
    #include <iomanip>
    
    #include "Operation.h"
    #include "Zahl.h"
    #include "Programm.h"
    
    using namespace std;
    
    void operator<<(ostream& os, const Programm& p)
    {
        p.anzeigen();
    }
    
    ostream& operator<<(ostream& os, const Zahl& z)
    {
        os << z.getwert();
        return os;
    }
    
    void datenVerarbeiten(Zahl v[], const int LEN)
    {
    	for(int j=0; j<LEN; j++)
    	{
    		for(int i=j+1; i<LEN; i++)
    		{
    			v[j] = v[j] + v[i];
    		}
    	}
    	v[LEN-1] = v[0] * v[LEN-1];
    }
    
    void datenAnzeigen(Zahl n[], const int LEN)
    {
    	stringstream s;
    	cout << endl;
    	for(int i=0; i<LEN; i++)
    	{
    		s   << "   "
    			<< "n[" << i << "] = "
    			<< setw(3) << left
    			<< n[i]
    			<< " (" << &n[i] << ")"
    			<< endl;
    	}
    	cout << s.str() << endl;
    }
    
    void datenInitialisieren(Zahl n[], const int LEN)
    {
        float f = 0.0;
        for(int i=0; i<LEN; i++)
    	{
            n[i] = ++f;
        }
    }
    
    int main()
    {
    	cout << "*** Ausfuehrung 1" << endl;
    	cout << "*** 1.1: Datenfeld initialisieren" << endl;
    	const int LEN = 4;
    	Zahl n[LEN];
    	datenInitialisieren(n,LEN);
    	datenAnzeigen(n,LEN);
    
    	cout << "*** 1.2: Daten verarbeiten und dabei die Verarbeitung als Programm aufzeichnen" << endl;
    	Programm programm;
    	Zahl::operationenAufzeichnen(&programm);
    	datenVerarbeiten(n,LEN);
    	Zahl::operationenAufzeichnen(nullptr);
    	datenAnzeigen(n,LEN);
    
    	cout << "*** 1.3: Aufgezeichnetes Programm anzeigen" << endl;
    	cout << programm;
    
    	cout << "*** Ausfuehrung 2" << endl;
    	cout << "*** 2.1: Datenfeld mit urspruenglichen Werten initialisieren" << endl;
    	datenInitialisieren(n,LEN);
    	datenAnzeigen(n,LEN);
    	cout << "*** 2.2: Aufgezeichnetes Programm ausfuehren" << endl;
    	programm.ausfuehren();
    	datenAnzeigen(n,LEN);
    }
    

    Zahl.h

    #pragma once
    #include <sstream>
    #include <iostream>
    
    #include "Programm.h"
    #include "Addition.h"
    #include "Multiplikation.h"
    #include "BinaerOperation.h"
    
    using namespace std;
    
    class Programm;
    
    class Zahl
    {
    private:
    	float wert;
    
    public:
    	static Programm* programm;
    	static bool rec;
    	friend Zahl* const ergebnis();
    	Zahl(float wert = 0);
    
    	Zahl(const Zahl& z);
    
        float getwert() const;
    
        void operator=(const float& f);
    
        void operator=(const Zahl& z);
    
    	Zahl operator+(Zahl& z) const;
    
    	Zahl operator*(Zahl& z) const;
    
    	static void operationenAufzeichnen(Programm* p);
    };
    
    bool Zahl::rec = false;
    Programm* Zahl::programm;
    

    Zahl.cpp

    #include <sstream>
    #include <iostream>
    
    #include "Zahl.h"
    
    using namespace std;
    
    Zahl::Zahl(float wert = 0)
    {
        this -> wert = wert;
    }
    
    Zahl::Zahl(const Zahl& z)
    {
        this -> wert = z.wert;
    }
    
    float Zahl::getwert() const
    {
    	return wert;
    }
    
    void Zahl::operator=(const float& f)
    {
        wert = f;
    }
    
    void Zahl::operator=(const Zahl& z)
    {
        wert = z.getwert();
    }
    
    Zahl Zahl::operator+(Zahl& z) const
    {
        Zahl summe;
        summe.wert = wert + z.getwert();
        if(rec)
        {
            Operation* add = new Addition(this, this, &z);
            programm->hinzufuegen(add);
        }
        return summe;
    }
    
    Zahl Zahl::operator*(Zahl& z) const
    {
        Zahl produkt;
        produkt.wert = wert * z.getwert();
        if(rec)
        {
            Operation* mul = new Multiplikation(&produkt, this, &z);
            programm->hinzufuegen(mul);
        }
        return produkt;
    }
    
    static void Zahl::operationenAufzeichnen(Programm* p)
    {
    	programm = p;
    	if(p != nullptr)
    		rec = true;
    }
    
    bool Zahl::rec = false;
    Programm* Zahl::programm;
    

    Programm.h

    #pragma once
    #include <sstream>
    #include <iostream>
    #include <vector>
    
    #include "Operation.h"
    
    using namespace std;
    
    class Programm
    {
    public:
        vector<Operation*> opv;
    
    public:
        static int operationCounter;
    
    	void hinzufuegen(Operation* op);
    	void ausfuehren () const;
    	void anzeigen   () const;
    };
    

    Programm.cpp

    #include <sstream>
    #include <iostream>
    #include <vector>
    
    #include "Programm.h"
    
    using namespace std;
    
    void Programm::hinzufuegen(Operation* op)
    {
    	opv.push_back(op);
    }
    
    void Programm::ausfuehren() const
    {
    	int i = 0;
    	LEER
        for(Operation* o : opv)
        {
            o->ausfuehren(i++);
        }
        LEER
    }
    
    void Programm::anzeigen() const
    {
    	LEER
        for(Operation* o : opv)
        {
            o->anzeigen();
        }
        LEER
    }
    

    Operation.h (Schnittstelle)

    #pragma once
    #include <sstream>
    #include <iostream>
    
    using namespace std;
    
    struct Operation
    {
        virtual void ausfuehren(int i) = 0;
        virtual void anzeigen() = 0;
    };
    

    BinaerOperation.h

    #pragma once
    #include <sstream>
    #include <iostream>
    
    #include "Zahl.h"
    #include "Operation.h"
    
    using namespace std;
    
    class Zahl;
    
    class BinaerOperation : public Operation
    {
    private:
    	const Zahl* operand1;
    	const Zahl* operand2;
    	const Zahl* ergebnis;
    	char  symbol;
    
    public:
        BinaerOperation(const Zahl* ergebnis, const Zahl* const operand1, const Zahl* operand2, char symbol);
        virtual ~BinaerOperation();
    
    protected:
    	char getsymbol() const;
        const Zahl* getErgebnis() const;
        const Zahl* getOperand1() const;
        const Zahl* getOperand2() const;
    };
    

    Binaeroperation.cpp

    #include <sstream>
    #include <iostream>
    
    #include "BinaerOperation.h"
    
    using namespace std;
    
    BinaerOperation::BinaerOperation(const Zahl* ergebnis, const Zahl* const operand1, const Zahl* operand2, char symbol)
    {
        this -> operand1 = operand1;
        this -> operand2 = operand2;
        this -> ergebnis = ergebnis;
        this -> symbol   = symbol;
    }
    virtual BinaerOperation::~BinaerOperation() {}
    char BinaerOperation::getsymbol() const { return symbol; }
    const Zahl* BinaerOperation::getErgebnis() const { return ergebnis; }
    const Zahl* BinaerOperation::getOperand1() const { return operand1; }
    const Zahl* BinaerOperation::getOperand2() const { return operand2; }
    

    Addition.h

    #pragma once
    #include <iostream>
    
    #include "BinaerOperation.h"
    
    using namespace std;
    
    ostream& operator<<(ostream& os, const Zahl& z);
    
    class Addition : public BinaerOperation
    {
    public:
        const Zahl* summe;
        const Zahl* summand1;
        const Zahl* summand2;
    
    	Addition(const Zahl* summe, const Zahl* const summand1, const Zahl* summand2);
    	void ausfuehren(int i);
    	void anzeigen();
    };
    

    Addition.cpp

    #include <iostream>
    
    #include "Addition.h"
    
    using namespace std;
    
    Addition::Addition(const Zahl* summe, const Zahl* const summand1, const Zahl* summand2) : BinaerOperation(summe, summand1, summand2, '+')
    {
    	this -> summand1 = summand1;
    	this -> summand2 = summand2;
    	this -> summe    = summe;
    }
    
    void Addition::ausfuehren(int i)
    {
    	cout << "Addition ausfuehren" << i << endl;
        cout << "summand1 = " << *summand1 << endl;
        cout << "summand2 = " << *summand2 << endl;
        cout << "summe    = " << endl;
    }
    
    void Addition::anzeigen()
    {
        cout << "   "
    	 << summe
    	 << " = "
    	 << summand1
    	 << " + "
    	 << summand2
    	 << endl;
    }
    

    Multiplikation.h

    #pragma once
    #include <iostream>
    
    #include "BinaerOperation.h"
    
    using namespace std;
    
    class Multiplikation : public BinaerOperation
    {
    public:
        Zahl* produkt;
        const Zahl* multiplikator;
        const Zahl* multiplikand;
    
    	Multiplikation(Zahl* produkt, const Zahl* const multiplikator, const Zahl* multiplikand);
    	void ausfuehren(int i);
    	void anzeigen();
    };
    

    Multiplikation.cpp

    #include <iostream>
    
    #include "Multiplikation.h"
    
    using namespace std;
    
    Multiplikation::Multiplikation(Zahl* produkt, const Zahl* const multiplikator, const Zahl* multiplikand) : BinaerOperation(produkt, multiplikator, multiplikand, '*')
    {
    	this -> multiplikator = multiplikator;
    	this -> multiplikand  = multiplikand;
    	this -> produkt       = produkt;
    }
    
    void Multiplikation::ausfuehren(int i)
    {
        cout << "Multiplikation ausfuehren" << endl;
        //hier muss ergänzt werden
    }
    
    void Multiplikation::anzeigen()
    {
        cout << "   "
    		 << produkt
    		 << " = "
    		 << multiplikator
    		 << " * "
    		 << multiplikand
    		 << endl;
    }
    


  • Wie schon gesagt : Es geht hier vor allem darum, die Includes richtig zu setzen / verstehen.
    Mit der Konstellation oben bekomme ich den Error (in Multiplikation.h)

    line 9: error: expected class-name before '{' token
    

    Daraus folgen dann die Fehler :

    line 11: error: 'Zahl' does not name a type
    line 12: error: 'Zahl' does not name a type
    line 13: error: 'Zahl' does not name a type
    line 15: error: expected ')' before '*' token
    


  • Hattest du meinen Beitrag vom 13:16:01 14.06.2016 überhaupt gelesen?

    Und wenn ja (du hattest den "Tippfehler" ja angeblich berichtigt): wie sieht deine Zeile 9 jetzt aus? (auch das hatte ich schon einmal gefragt)



  • Ah, irgendwie ist da der Fehler mit dem :: inzwischen scheinbar behoben. Mir fallen noch alle möglichen anderne Dinge auf:

    1. Bitte niemals "using namespace ..." innerhalb eines Headers nutzen.
    2. Ich hatte es schon angemerkt, dass du in Addition und Multiplikation die Zahlen nicht speichern sollst - und nun, nachdem ich das UML sehe, bestätigt sich das. Auch in diesem UML wird diese Doppelspeicherung nicht vorgenommen. Dafür sind doch extra getOperand1 und 2 da!

    Eigentlicher Fehler: es sind so viele Dateien, die copy-paste ich jetzt nicht alle einzeln, um den Fehler zu reproduzieren, sorry. Vielleicht hast du irgendwo ein Include vergessen? Und ist

    line 9: error: expected class-name before '{' token

    wirklich der vollständige Fehler? Gibt es nicht vielleicht ein paar Zeilen davor/danach, die mehr Aufschluss geben?



  • Vielen Dank für deine Hilfe.

    Ja ich hatte den Beitrag gelesen, und der Fehler blieb derselbe, da der Fehler sich auf die Multiplikation.h bezogen hat, und nicht auf die verbesserte Multiplikation.cpp.

    Zu 1: Danke, das hatte ich bisher noch nicht gewusst.
    Liegt das daran, dass man die Std Lib in headern nicht braucht, wenn man zugehörige .cpp Dateien hat ?

    Zu 2: D.h. ich übergebe die direkt an BinaerOperation, richtig ?

    Zu 3: In meinem letzten Post habe ich alle 5 resultierenden Fehler gepostet. Außer dem von dir genannten sind das noch 4 weitere.

    Falls es hilft (und um das Copy-Paste zu umgehen, sind hier alle Dateien als Download).

    https://drive.google.com/file/d/0B8p3-t4oD8EidUpIUmdmVnhJSE0/view?usp=sharing

    Nochmals danke !



  • Was sollen die include in Zahl.h?
    Was soll die Definition der static member im Zahl.h?



  • 1: Eine Zahl muss von Addition, Multiplikation und BinaereOperation neue Objekte erstellen. Außerdem wird auch ein static Programm angelegt. Deswegen hab ich diese Header includet. War das falsch ?

    2: Ich geh davon aus, dass man das in der .cpp macht. Ich hab bisher aber nur Header für Klassen verwendet und kenn mich deswegen da noch nicht so ganz aus. Danke für den Tipp.



  • jasperjodler schrieb:

    1: Eine Zahl muss von Addition, Multiplikation und BinaereOperation neue Objekte erstellen.

    Blödsinn. Eine Zahl ist eine Zahl, die muss nicht wissen, ob sie multipliziert werden kann. Umgekehrt: die Multiplikation oder Addition muss natürlich die Zahl kennen!

    Also alle deine Header kannst du aus Zahl.h rauswerfen!

    Im Multiplikation.h verwendest du dagegen die Klasse Zahl. Damit das geht, muss sie bekannt sein. Also include darin die Zahl.h. Oder, da du nur Zahl* verwendest, sag einfach am Anfang des Headers mit "class Zahl;" bescheid, dass Zahl eine Klasse ist.

    Dann wäre es noch nett zu wissen, wie du kompilierst (wie lautet deine Kommandozeile oder hast du ein Makefile?). Mit g++ -std=c++11 -Wall -Wextra ... bekomme ich doch sehr viele Warnungen und auch Fehler.



  • jasperjodler schrieb:

    1: Eine Zahl muss von Addition, Multiplikation und BinaereOperation neue Objekte erstellen.

    Zeige mir eine Zeile im Header, in der das vorkommt.

    Außerdem wird auch ein static Programm angelegt. Deswegen hab ich diese Header includet.

    Dafür reicht das vorhandene class Programm aus.

    Dein Problem sind höchstwahrscheinlich zyklische include, und in Zahl legst du die Grundlagen dafür.



  • So, jetzt habe ich alle Header aus Zahl.h rausgeworfen. Dann bekomme ich die Fehlermeldung :

    In member function 'Zahl Zahl::operator+(Zahl&) const':
    
    Zahl.cpp |39| error: 'Operation' was not declared in this scope|
    Zahl.cpp |39| error: 'add' was not declared in this scope|
    Zahl.cpp |39| error: expected type-specifier before 'Addition'|
    Zahl.cpp |40| error: invalid use of incomplete type 'class Programm'|
    Zahl.h   |7 | error: forward declaration of 'class Programm'|
    
    In member function 'Zahl Zahl::operator*(Zahl&) const':
    
    Zahl.cpp |51| error: 'Operation' was not declared in this scope|
    Zahl.cpp |51| error: 'mul' was not declared in this scope|
    Zahl.cpp |51| error: expected type-specifier before 'Multiplikation'|
    Zahl.cpp |52| error: invalid use of incomplete type 'class Programm'
    Zahl.h   |7 | error: forward declaration of 'class Programm'
    

    Das habe ich aber eigentlich auch erwartet, da ich ja die include Multiplikation und Addition rausgelöscht habe.

    Hier nochmal der relevante Code mit Zeilenangaben:
    Zahl.h

    #pragma once
    #include <sstream>
    #include <iostream>
    
    using namespace std;
    
    class Programm;
    
    class Zahl
    {
    private:
        float wert;
    
    public:
        static Programm* programm;
        static bool rec;
        friend Zahl* const ergebnis();
        Zahl(float wert = 0);
        Zahl(const Zahl& z);
        float getwert() const;
        void operator=(const float& f);
        void operator=(const Zahl& z);
        Zahl operator+(Zahl& z) const;
        Zahl operator*(Zahl& z) const;
        static void operationenAufzeichnen(Programm* p);
    };
    

    Zahl.cpp

    #include <sstream>
    #include <iostream>
    
    #include "Zahl.h"
    
    using namespace std;
    
    Zahl::Zahl(float wert)
    {
        this -> wert = wert;
    }
    
    Zahl::Zahl(const Zahl& z)
    {
        this -> wert = z.wert;
    }
    
    float Zahl::getwert() const
    {
        return wert;
    }
    
    void Zahl::operator=(const float& f)
    {
        wert = f;
    }
    
    void Zahl::operator=(const Zahl& z)
    {
        wert = z.getwert();
    }
    
    Zahl Zahl::operator+(Zahl& z) const
    {
        Zahl summe;
        summe.wert = wert + z.getwert();
        if(rec)
        {
            Operation* add = new Addition(this, this, &z);
            programm->hinzufuegen(add);
        }
        return summe;
    }
    
    Zahl Zahl::operator*(Zahl& z) const
    {
        Zahl produkt;
        produkt.wert = wert * z.getwert();
        if(rec)
        {
            Operation* mul = new Multiplikation(&produkt, this, &z);
            programm->hinzufuegen(mul);
        }
        return produkt;
    }
    
    void Zahl::operationenAufzeichnen(Programm* p)
    {
    	programm = p;
    	if(p != nullptr)
    		rec = true;
    }
    
    bool Zahl::rec = false;
    Programm* Zahl::programm;
    

    Meine Kommandozeilenargumente sind :

    g++ -std=c++11 -Wall
    


  • Die Fehlermeldung ist in deiner cpp-Datei. Dort musst du die entsprechenden Header natürlich includen!



  • Danke Leute für eure Hilfe !

    Jetzt funktioniert alles. Ich hab noch das Programm und die ausfuehren()- Funktionen fertig geschrieben, und jetzt kann das Programm die Rechnungen nachstellen.

    Vielen Dank.


Anmelden zum Antworten