Erstes OOP Projekt - Erschaffung einer Instanz namens Person - gelöst



  • Th69 schrieb:

    Der Begriff Dependency Injection (DI) bzw. Inverse of Control (IoC) wird z.B. auch in C# benutzt.

    Sorry, aber C# ist Java.



  • Th69 schrieb:

    Beim Test Driven Design (TDD) ist damit DI quasi fest vorgegeben.

    Das sehe ich in C++ nicht.



  • Naja, in Java muss man das Strategy Pattern auch per Interface und Polymorphie implementieren. In C++ geht das ganze über Templates, damit ist es schneller, typsicherer und hat zur Laufzeit keine ungeplanten Nebeneffekte.

    Nachteil ist damit aber die Nicht-Substituierbarkeit zur Laufzeit



  • Th69 schrieb:

    Der Begriff Dependency Injection (DI) bzw. Inverse of Control (IoC) wird z.B. auch in C# benutzt.
    Es ermöglicht besonders, einzelne Klassen und Methoden besser testen zu können, indem Abhängigkeiten zu externen Klassen (z.B. externe Ressourcenzugriffe, Logger, ...) durch Schnittstellen ersetzt werden, so daß diese durch (dummy) Mock-Implemenationen ersetzt werden (d.h. es wird nur die Funktionalität der eigentlich zu testenden Methode betrachtet).
    Beim Test Driven Design (TDD) ist damit DI quasi fest vorgegeben.

    Machst du das wirklich so aufwändig? Für jeden Kram Mocks schreiben, damit du nur die Funktionalität der Klasse bzw. ein paar zusammengehörender Kassen einzeln testen kannst? Machst du dann auch noch Tests damit du weißt, ob die Klassen auch wirklich mit den anderen nichtmehr gemockten Klassen funktionieren, so wie sie im Programm dann verwendet werden?



  • Erst einmal vielen Dank für das rege Interesse und den vielen Antworten.

    Ich bin dem Ziel bisschen näher gekommen.

    In der Header-Datei "Klasse Person.h" habe ich folgende Deklaration gemacht:

    #pragma once 
    #include <string>
    using namespace std;
    
    class Person
    {
    private:
    	string Vorname;
    	string Nachname;
    	int Alter;
    
    public:
    	Person();
    	~Person();
    
    	string getVorname();
    	string getNachname();
    	int getAlter();
    	void setVorname(string);
    	void setNachname(string);
    	void setAlter(int);
    
    };
    

    In "Klasse Person.cpp" habe ich folgende Implementierung geschrieben:

    #include <iostream>
    #include "Klasse Person.h"
    using namespace std;
    
    Person::Person(void)
    {
    
    }
    
    Person::~Person()
    {
    
    }
    
    string Person::getVorname()
    {
    	return Vorname;
    }
    
    string Person::getNachname()
    {
    	return Nachname;
    }
    
    int Person::getAlter()
    {
    	return Alter;
    }
    
    void Person::setVorname(string vn)
    {
    	Vorname = vn;
    }
    
    void Person::setNachname(string nn)
    {
    	Nachname = nn;
    }
    
    void Person::setAlter(int age)
    {
    	Alter = age;
    }
    

    In "Person APP.cpp" habe ich folgenden Code geschrieben:

    #include <iostream>
    #include "Klasse Person.h"
    using namespace std;
    
    #define MAX_ANZAHL 2
    
    void einePerson()
    {
    	string str;
    	Person Passant; 
    
    	cout << "Wie ist ihr Vorname?\n";
    	cin  >> str;
    	Passant.setVorname(str);
    
    	cout << "Wie ist Ihr Nachname?}n";
    	cin  >> str;
    	Passant.setNachname(str);
    
    	cout << "Wie alt sind Sie?\n";
    	int age;
    	cin  >> age;
    	Passant.setAlter(age);
    
    	cout << "\n";
    	cout << "Das haben Sie eingegeben:\n";
    	cout << "\n";
    	cout << "Vorname:    " << Passant.getVorname() << "\n";
    	cout << "Nachname:   " << Passant.getNachname() << "\n";
    	cout << "Alter:      " << Passant.getAlter() << "\n";
    
    }
    
    void mehrerePersonen()
    {
    	Person Personen[MAX_ANZAHL];
    
    	for(int i=0; i<MAX_ANZAHL; i++)
    	{
    		string str;
    
    		cout << "Wie ist ihr Vorname?\n";
    		cin  >> str;
    		Personen[i].setVorname(str);
    
    		cout << "Wie ist Ihr Nachname?\n";
    		cin  >> str;
    		Personen[i].setNachname(str);
    
    		cout << "Wie alt sind Sie?\n";
    		int age;
    		cin  >> age;
    		Personen[i].setAlter(age);
    
    	}
    }
    
    int main()
    {
    	//einePerson();
    
    	mehrerePersonen();
    
    	return 0;
    }
    

    Jetzt hätte ich nur ein Anliegen...

    Was ist

    #pragma once
    

    ?? Was bedeutet der Befehl?

    Gruß

    Max



  • Sagt dem Compiler, dass der Header nicht nochmal eingebunden wird. Das ist interessant sobald eine Quelldatei 2 Header einbindet, die beide einen dritten Header einbinden. (Der dann doppelt eingebunden ist, der Compiler streikt dann nämlich)

    Es gibt 2 Optionen:

    Include-Guards (portabel):

    #ifndef _FOO_HPP_INCLUDED_ // Oder irgendein anderer, einzigartiger Name.
    #define _FOO_HPP_INCLUDED_
    
    .... Code ...
    
    #endif // _FOO_HPP_INCLUDED_
    

    oder eben per Pragma (eher unportabel)

    #pragma once 
    
    .... Code ...
    

    Jede Headerdatei sollte eines von beiden machen. (Ja, nicht ganz jede, aber praktisch jede)



  • Denn nehmen wir mal an, du hast folgende Situation:

    // header1.h
    void foo();
    
    // header2.h
    #include "header1.h"
    void bar();
    
    // main.cpp
    #include "header1.h"
    #include "header2.h"
    

    Nach dem Einbinden der Header, sieht es in main.cpp so aus:

    void foo(); // aus header1.h
    
    void foo(); // aus header1.h in header2.h
    void bar(); // aus header2.h
    

    Der Linker beschwert sich nun, dass die Funktion foo() zweimal deklariert wurde.
    Mit #pragma once oder include-Gurads wird jeder Header nur einmal eingebunden, das sieht dann so aus:

    void foo(); // aus header1.h
    
    // header1.h aus header2.h wird nicht eingebunden, weil header1.h bereits inkludiert wurde
    void bar(); // aus header2.h
    

    Edit: Nochmal etwas zum Stil: kein using namespace std in Headern, schreibe stattdessen std::string!



  • Nathan schrieb:

    Edit: Nochmal etwas zum Stil: kein using namespace std in Headern, schreibe stattdessen std::string!

    Warum kein

    using namespace std;
    

    verwenden??

    Ist denn der Code bisher sonst in Ordnung??



  • silent_max schrieb:

    Nathan schrieb:

    Edit: Nochmal etwas zum Stil: kein using namespace std in Headern, schreibe stattdessen std::string!

    Warum kein

    using namespace std;
    

    verwenden??

    Ist denn der Code bisher sonst in Ordnung??

    Weil du dir vorstellen kannst, dass der Inhalt jeder Headerdatei, die per include eingebunden wird, direkt in die Datei reinkopiert wird, die sie einbindet. Macht ein Header using namespace xxxx, dann gilt das in jeder Headerdatei die danach eingebunden wird und in jeder Sourcedatei - es hebelt also komplett den Zweck von Namensräumen aus.



  • Hallo liebe Gemeinde.

    Euch wird das Thema wahrscheinlich schon zum Hals raus hängen, aber ich verstehe es immer noch nicht ganz.

    Ich wollte dem ganzen Code noch eine Abfrage nach der Postleitzahl hinzufügen.

    Also in "Klasse Person.h" habe ich geschrieben:

    class Person
    {
    private:
      int Postleitzahl;
    
    public:
      int getPostleitzahl;
      void setPostleitzahl(int);
    }
    

    In "Klasse Person.cpp" habe ich geschrieben:

    int Person::getPostleitzahl()
    {
      return Postleitzahl;
    }
    
    void Person::setPostleitzahl(int postcode)
    {
      Postleitzahl = postcode;
    }
    

    Hier bekomme ich die Fehlermeldung, dass bei getPostleitzahl()

    Error: Die Deklaration ist nicht mit "int Person::getPostleitzahl" kompatibel
    

    In "Person APP.cpp" habe ich geschrieben:

    cout << "Wo wohnen Sie? Geben Sie die Postleitzahl an!\n";
      int Postleitzahl;
      cin  >> Postleitzahl;
      Personen[i].setPostleitzahl(postcode)
    

    Hier bekomme ich folgende Fehlermeldung:

    Error: "class "Person"" hat keinen Member "setPostleitzahl"
    Error: Der Bezeichner ""postcode"" ist nicht definiert
    

    Wo ist mein Denkfehler??

    Gruß

    Max



  • Klammern bei Deklaration vergessen.
    Und diverse Semikolons.



  • Also ich habe die vermeintlichen (Leichtsinns-) Fehler ausgebessert, dennoch kommen in der "Person APP.cpp" die Meldungen

    Error: "class "Person"" hat keinen Member "setPostleitzahl"
    Error: Der Bezeichner ""postcode"" ist nicht definiert
    

    Ich sehe es echt nicht, wo der Fehler ist...



  • silent_max schrieb:

    Also ich habe die vermeintlichen (Leichtsinns-) Fehler ausgebessert, dennoch kommen in der "Person APP.cpp" die Meldungen

    Error: "class "Person"" hat keinen Member "setPostleitzahl"
    Error: Der Bezeichner ""postcode"" ist nicht definiert
    

    Ich sehe es echt nicht, wo der Fehler ist...

    Ohne Quellcode sehe ich hier auch nichts 😛



  • Also hier mal der gesamte Quellcode:

    In "Klasse Person.h"

    #pragma once
    #include <string>
    using namespace std;
    
    class Person
    {
    private:
      string Vorname;
      string Nachname;
      int Alter;
      int Postleitzahl;
    
    public:
      Person();
      ~Person();
    
      string Vorname();
      string Nachname();
      int getAlter();
      int Postleitzahl();
      void setVorname(string);
      void setNachname(string);
      void setAlter(int);
      void setPostleitzahl(int);
    };
    

    In "Klasse Person.cpp":

    #include <iostream>
    #include "Klasse Person.h"
    using namespace std;
    
    Person(void)
    {
    
    }
    
    ~Person()
    {
    
    }
    
    string Person::getVorname()
    {
      return Vorname;
    }
    
    string Person::getNachname()
    {
      return Nachname;
    }
    
    int Person::getAlter()
    {
      return Alter;
    }
    
    int Person::getPostleitzahl()
    {
      return Postleitzahl;
    }
    
    void Person::setVorname(string vn)
    {
      Vorname = vn;
    }
    
    void Person::setNachname(string nn)
    {
      Nachname = nn;
    }
    
    void Person::setAlter(int age)
    {
      Alter = age;
    }
    
    void Person::setPostleitzahl(int postcode)
    {
      Postleitzahl = postcode;
    }
    

    In "Person APP.cpp" habe ich geschrieben:

    #include <iosteram>
    #include "Klasse Person.h"
    using namespace std;
    
    #define MAX_ANZAHL 2
    
    void einePerson()
    {
      string str;
      Person Passant;
    
      cout << "Wie ist Ihr Vorname?\n";
      cin  >> str;
      Passant.setNachname(str);
    
      cout << "Wie ist Ihr Nachname?\n";
      cin  >> str;
      Passant.setNachname(str);
    
      cout << "Wie alt sind Sie?\n"
      int age;
      cin  >> age;
      Passant.setAlter(age);
    
      cout << "\n";
      cout << "Das haben Sie eingegeben: \n";
      cout << "\n";
      cout << "Vorname:  " << Passant.getVorname() << "\n";
      cout << "Nachname: " << Passant.getNachname() << "\n";
      cout << "Alter:    " << Passant.getAlter() << "\n";
    }
    
    void mehrerePersonen()
    {
      Person Personen[MAX_ANZAHL];
    
      for (int i = 0; i < MAX_ANZAHL; i++)
      {
        string str;
    
        cout << "Wie ist Ihr Vorname?\n";
        cin  >> str;
        Personen[i].setNachname(str);
    
        cout << "Wie ist Ihr Nachname?\n";
        cin  >> str;
        Personen[i].setNachname(str);
    
        cout << "Wie alt sind Sie?\n";
        int age;
        cin  >> age;
        Personen[i].setAlter(age);
    
        cout << "Wo wohnen Sie? Geben Sie Ihre Postleitzahl an!\n";
        int Postleitzahl;
        cin  >> Postleizahl;
        Personen[i].setPostleitzahl(postcode);
        }
    }
    
    int main()
    {
      //einePerson();
    
      mehrerePersonen();
    
      return 0;
    }
    

    Ich weiß echt nicht, wo der Fehler sein kann...



  • puh also mein Compiler spuckt mit 20 Fehler oder so aus. Es fehlen ein paar get-Funktionen. Ich weiß auch nicht, ober Header ein Leerzeichen enhalten dürfen? Konstruktor und Destruktor wurden nicht definiert. Bei getAlter ist ein hast du "get Alter" geschrieben, mit dem Leerzeichen. 😃



  • [quote="silent_max"

    int Postleitzahl;
        cin  >> Postleizahl;
        Personen[i].setPostleitzahl(postcode);
    

    Ich weiß echt nicht, wo der Fehler sein kann...[/quote]
    In diesen drei Zeilen.



  • Sorry, habe ich echt nicht mehr gesehen...

    Jetzt wird mir nur noch "postcode" rot unterringelt...

    Error: Der Bezeichner ""postcode"" ist nicht definiert
    

    Edit:

    Ich habe doch in "Klasse Person.cpp" folgenden Code geschrieben:

    void Person::set Postleitzahl(int postcode)
    {
      Postleitzahl = postcode;
    }
    

    Ich verstehe an der Stelle nicht, warum mir dann in "Person APP.cpp" dann "postcode" rot unterringelt wird...



  • silent_max schrieb:

    Sorry, habe ich echt nicht mehr gesehen...

    Jetzt wird mir nur noch "postcode" rot unterringelt...

    Error: Der Bezeichner ""postcode"" ist nicht definiert
    

    JOa weil postcode nirgendwo definiert ist. Musst noch wo definieren, in der Funktion.



  • Nathan schrieb:

    silent_max schrieb:

    int Postleitzahl;
        cin  >> Postleizahl;
        Personen[i].setPostleitzahl(postcode);
    

    Ich weiß echt nicht, wo der Fehler sein kann...

    In diesen drei Zeilen.



  • Du wirst dir viele Fehler und Zeit sparen, wenn du von vornerein die Signaturen der Funktionsdeklaration und -definition identisch hälst.


Anmelden zum Antworten