#includes in header auslagern / nur einmal schreiben


  • Mod

    Malgus schrieb:

    Ich hatte grade mal versucht einen namespace zu erstellen, um in der multi_rotae.cpp nicht immer multi_rotae:: schreiben zu müssen. Hat leider nicht so geklappt. Gibts ne andere Möglichkeit, sich das zu sparen?

    Nein, außer du definierst die Methoden direkt in der Klassendefinition. Was dann aber wieder eine subtil andere Bedeutung hat, da die Methoden dann inline sind.

    endl steht für neue Zeile, stattdessen kann auch \n in einem string verwendet werden.

    Wie du vielleicht schon bemerkt hast, wird dir nur Scheiß beigebracht.



  • Malgus schrieb:

    Werd jetzt mal googeln, was das macht und ggf. \n verwenden

    Da brauchst du nicht lange googeln, da gibts mitterweile auch schon einen Thread. 😉
    http://www.c-plusplus.net/forum/308808-full?highlight=flush



  • Da ich immernoch keinen Plan habe was im namespace std so alles drin steht und mich das langsam gruselt, hab ich grade aufgehört, using namespace std zu verwenden 😉
    Sieht dann in der main.cpp so aus:

    using ::std::endl;
    using ::std::cout;
    using ::std::cin;
    using ::std::string;
    using ::std::setiosflags;
    using ::std::ios;
    using ::std::setw;
    

    😃

    Hab jetzt einige endl's durch \n ersetzt. Hab aber immer die letzten in eienr Methode so gelassen, damit zum Beispiel bei Fehlern die Ausgabe bis dahin aktualisiert ist.

    Ich verwende inzwischen beim cout ein setiosflags(ios::left)
    Macht es Sinn, das am Programmende noch zu reseten? (Zentrieren geht nicht, oder?)
    Setw() muss ich auch benutzen, das wird aber nicht erklärt. Sehe ich das richtig, dass das einfach die Feldbreite des nächsten Ausgabeelements setzt? Was passiert, wenn mein Element breiter ist? Oder wenn ich da ein \n oder ein endl reinschreibe?

    Mir scheint, die wollen nur, dass wir irgendwie die Aufgabe schaffen, aber nicht, dass wir ordentlich programmieren lernen. Deswegen muss ich jetzt anscheinend alles hier nachfragen oder googeln, was evt. irgendwelche Sachen tun könnte... Doll 😞

    Naja, hoffe ihr nehmt mir das nicht übel und beantwortet meine Fragen weiter so nett und fleissig :).


  • Mod

    Malgus schrieb:

    Macht es Sinn, das am Programmende noch zu reseten?

    Nein. Formatierung betrifft nur dein Programm.

    (Zentrieren geht nicht, oder?)

    Nicht direkt, musst du selber programmieren. Ist derzeit wahrscheinlich noch deutlich über deinem Kenntnisstand

    Setw() muss ich auch benutzen, das wird aber nicht erklärt. Sehe ich das richtig, dass das einfach die Feldbreite des nächsten Ausgabeelements setzt? Was passiert, wenn mein Element breiter ist? Oder wenn ich da ein \n oder ein endl reinschreibe?

    Am besten einfach ein bisschen experimentieren und Beispiele angucken, z.B. hier:
    http://www.cplusplus.com/reference/iostream/manipulators/



  • Hui, ich hab im Skript doch noch die Erklärung zu den namespaces gefunden. Irgendwo versteckt zwischen den Erklärungen zu Klassen. Das macht es zwar nicht sinnvoller, es sich falsch anzugewöhnen, aber naja, zumindest steht da, dass man das eig. nicht machen sollte.

    Habe jetzt aber ein anderes Problem:

    //aus der main.cpp :
    //es gibt eine globale Variable dGlobaleZeit (mit =0.0 initialisiert)
    
    for(int i=1; i<10; i++){
    	dGlobaleZeit+=i/10;
    
    	vehikel3->vAbfertigung();
    	vehikel2.vAbfertigung();
    	vehikel1.vAbfertigung();
    	vehikel3->vAusgabe();
    	vehikel2.vAusgabe();
    	vehikel1.vAusgabe();
    }
    
    //aus der multi_rotae.cpp 
    
    void multi_rotae::vAusgabe(){
    
    	cout << setw(5) << p_uiID << setw(10) << p_sName << setw(5) << ':' << setw(15) << p_dMaxSpeed << setw(15) << p_dKMCount << endl;
    
    }
    
    void multi_rotae::vAbfertigung(){
    	extern double dGlobaleZeit; //hab vorher versucht, das am Anfang dieser .cpp bekannt zu machen, Fehler bleibt aber
    	if (dGlobaleZeit-p_dTimeCount){
    		double dVergZeit=dGlobaleZeit-p_dTimeCount;
    		p_dKMCount+=dVergZeit*p_dMaxSpeed;
    		p_dTimeCount=dGlobaleZeit;
    	}
    	else {cerr << p_sName << "wurde grade zum zweiten Mal aufgerufen";}
    
    }
    

    Bei jedem Aufruf der vAbfertigung geht das Programm in den else Teil. Anscheinend ist 0.1-0 nicht true. Beide Variablen sind vom Typ double. Wenn ich dGlobaleZeit = i; setze gehts.


  • Mod

    Wenn du schon willst, dass sich jemand durch globale-Variablen-Spaghetticode wühlt, dann gib bitte ein vollständiges Programm. Siehe dritter Link in meiner Signatur.

    0.1-0 ist true, folglich wird das wohl nicht 0.1-0 sein, wo du denkst, es wäre 0.1-0. Ein Debugger hilft auch ungemein. Das wichtigste Werkzeug des Programmierers, besonders wenn man es mit einem schwer nachvollziehbarem Programm zu tun hat.

    Habe ich eigentlich schon gesagt, dass ihr nur Mist beigebracht bekommt?



  • Die Typpraefixe sind ekelhaft.



  • Die Typpraefixe hab ich mir nicht ausgesucht.

    if (dGlobaleZeit-p_dTimeCount)

    Es geht um die Zeile. Sobald dGlobaleZeit >= 1 wird, geht er in die if Schleife rein. Vorher geht er in das else. p_dTimeCount ist definitv 0. Beide sind vom Typ double. Meine Vermutung ist, dass irgendeine Art von abrundendem Typecast geschieht (macht es nen int draus und prüft dann erst?). Ich häng aber noch den ganzen Code hinten an.

    Habs auch mal damit probiert, aber erst wenn dGlobaleZeit 1 wird, ist die Bedingung erfüllt ...
    if (double test=dGlobaleZeit-p_dTimeCount>0)

    Gesamter Code:

    //multi_rotae.h
    #ifndef multirotae
    #define multirotae
    #include <string>
    
    class multi_rotae
    {
    private:
    	std::string p_sName;
    	unsigned int p_uiID;
    	double p_dMaxSpeed;
    	double p_dKMCount;
    	double p_dTimeCount;
    	double p_dCount;
    	multi_rotae(multi_rotae&);
    	static unsigned int p_uiMaxID;						
    	void vInitialisierung();
    
    public:
    
    	multi_rotae(void);
    	multi_rotae(std::string p_sName);
    	multi_rotae(std::string p_sName, double p_MaxSpeed);
    	virtual ~multi_rotae(void);
    	void vAusgabe();
    	void vAbfertigung();
    };
    #endif //multirotae
    
    //main.cpp
    
    #include <string>
    #include <iostream>
    #include <iomanip>
    
    #include "multi_rotae.h"
    
    //namespace std:
    using ::std::endl;
    using ::std::cout;
    using ::std::cin;
    using ::std::string;
    using ::std::setiosflags;
    using ::std::ios;
    using ::std::setw;
    
    //namespace std end -- no more includes after this!!
    
    double dGlobaleZeit=0.0;
    
    void vAufgabe1();
    
    void main(){
    
    vAufgabe1();
    
    }
    
    void vAufgabe1(){
    multi_rotae vehikel1("audo1", 50.5);
    multi_rotae vehikel2;
    string s_Name_vehikel3;
    cout << "Fahrzeugnamen eingeben" << '\n';
    cin >> s_Name_vehikel3;
    multi_rotae *vehikel3 = new multi_rotae(s_Name_vehikel3);
    cout << setiosflags(ios::left) << setw(5) << "ID" << setw(10) << "Name" << setw(5) << ':' << setw(10) << "MaxSpeed" << setw(20) << 
    	"GesamtStrecke" <<"\n++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n";
    for(int i=1; i<10; i++){
    	dGlobaleZeit+=i/5;
    
    	vehikel3->vAbfertigung();
    	vehikel2.vAbfertigung();
    	vehikel1.vAbfertigung();
    	vehikel3->vAusgabe();
    	vehikel2.vAusgabe();
    	vehikel1.vAusgabe();
    }
    delete vehikel3; 
    return;
    }
    
    //multi_rotae.cpp
    
    #include <string>
    #include <iostream>
    #include <iomanip>
    
    #include "multi_rotae.h"
    
    //namespace std:
    using ::std::endl;
    using ::std::cout;
    using ::std::string;
    using ::std::setw;
    using ::std::cerr;
    
    //namespace std end -- no more includes after this!!
    
    unsigned int multi_rotae::p_uiMaxID=0;
    
    void multi_rotae::vInitialisierung(void){
    	p_dMaxSpeed=0;
    	p_dKMCount=0;
    	p_dTimeCount=0;
    	p_dCount=0;
    	p_uiID=++p_uiMaxID;
    	p_sName="";
    }
    
    multi_rotae::multi_rotae(void)
    {
    	vInitialisierung();
    	cout << "born: " << p_sName << '\n';
    	cout << "id: " << p_uiID << endl;
    
    }
    
    multi_rotae::multi_rotae(string itself, double dMaxSpit)
    {
    	vInitialisierung();
    	p_dMaxSpeed=dMaxSpit;
    	p_sName=itself;
    	cout << "born: " << p_sName << '\n';
    	cout << "id: " << p_uiID << endl;
    
    }
    
    multi_rotae::multi_rotae(string itself)	{
    	vInitialisierung();
    	p_sName=itself;
    	cout << "born: " << p_sName << '\n';
    	cout << "id: " << p_uiID << '\n';
    	cout << "Highest Speed: " << p_dMaxSpeed << endl;
    
    }
    
    multi_rotae::~multi_rotae(void)
    {
    	cout << "trashed: " << p_sName << '\n';
    	cout << "id: " << p_uiID << '\n';
    	cout << "Highest Speed: " << p_dMaxSpeed << endl;
    
    }
    
    void multi_rotae::vAusgabe(){
    
    	cout << setw(5) << p_uiID << setw(10) << p_sName << setw(5) << ':' << setw(15) << p_dMaxSpeed << setw(15) << p_dKMCount << endl;
    
    }
    
    void multi_rotae::vAbfertigung(){
    	extern double dGlobaleZeit;
    	if (dGlobaleZeit-p_dTimeCount){
    		double dVergZeit=dGlobaleZeit-p_dTimeCount;
    		p_dKMCount+=dVergZeit*p_dMaxSpeed;
    		p_dTimeCount=dGlobaleZeit;
    	}
    	else {cerr << p_sName << "wurde grade zum zweiten Mal aufgerufen";}
    
    }
    

  • Mod

    i/5 ist 0 für i < 5. Integerdivision.

    Das Programm ist grauenhaft². Aber es nutzt wohl nichts, konkrete Verbesserungen vorzuschlagen, wenn dir alles vorgegeben ist. Du Armer 😞 .



  • Danke, jetzt klappts.

    Auch wenn ich das meiste nicht ändern kann, wie würde man es denn besser machen?
    Pointer hätt ich nicht benutzt, die vInitialisierung macht wenig Sinn, die ganzen Namen gehen mir auf den Senkel, aber den Typ in den Variablennamen zu schreiben find ich nachvollziehbar. Die cout's in Konstruktoren und Destruktor sind zu Testzwecken (vorgegeben). Ob man die Zeit wirklich global machen muss, weiss ich nicht.

    Bei der vAbfertigung war vorgegeben, dass die Variablen aktualisiert werden falls die Funktion in diesem Zeitabschnitt nicht schonmal aufgerufen wurde. Die cerr hab ich noch dazu gesetzt, um das wenigstens mitzukriegen, denn eig. sollen die in einem Zeitabschnitt nicht mehrfach abgehandelt werden.

    Ansonsten fällt mir nichts auf, aber wissen würds ichs schon gerne - ich seh nicht ein, stundenlang etwas falsch zu lernen, nur um irgendein Praktikum zu bestehen.


  • Mod

    Tut mir leid, aber das ist einfach ungeheuer viel, was daran schlecht ist. Da sitze ich stundenlang dran, das alles zu erklären.

    Bezüglich Typen im Variablennamen trifft es dieser Beitrag meiner Meinung nach ganz gut:
    http://www.c-plusplus.net/forum/p1773551#1773551



  • Und das ist erst Aufgabe 1 von 9 ;).
    Es wird also noch viel lustiger 🙄
    Dann mal danke, ich mach jetzt erstmal weiter, mal schauen, wann wieder was nicht klappt.


Anmelden zum Antworten