1. Liebe Forumsgemeinde,

    aufgrund der Bestimmungen, die sich aus der DSGVO ergeben, müssten umfangreiche Anpassungen am Forum vorgenommen werden, die sich für uns nicht wirtschaftlich abbilden lassen. Daher haben wir uns entschlossen, das Forum in seiner aktuellen Form zu archivieren und online bereit zu stellen, jedoch keine Neuanmeldungen oder neuen Kommentare mehr zuzulassen. So ist sichergestellt, dass das gesammelte Wissen nicht verloren geht, und wir die Seite dennoch DSGVO-konform zur Verfügung stellen können.
    Dies wird in den nächsten Tagen umgesetzt.

    Ich danke allen, die sich in den letzten Jahren für Hilfesuchende und auch für das Forum selbst engagiert haben. Ich bin weiterhin für euch erreichbar unter tti(bei)pcwelt.de.
    Dismiss Notice

C++: Klassenaufruf (.cpp und .h) in main einbinden

Discussion in 'Programmieren' started by noob222, Sep 6, 2009.

Thread Status:
Not open for further replies.
  1. noob222

    noob222 Byte

    Hallo,

    habe eine Header-Datei (Person.h), eine Implementierung (Person.cpp) und eine main.cpp.

    Wenn ich die Implementierung der Person.cpp in die main einfüge, dann klappt mein Programm wunderbar. Da ich gerade bisschen rumexperementiere und mir C++ aneigne, werde ich in der main bestimmt noch weitere Codes einfügen. Daher wollte ich es mir von anfang an übersichtlicher gestalten, in dem ich eine extra Klasse Person.cpp erzeuge.

    Irgendwie kriege ich es nicht hin, dass ich in der main auf Person.cpp zugreifen kann um die Methode Do() auszuführen. Die Methode Do() aus der Klasse Person.cpp soll mir in der Konsole die Ausgabe zeigen.

    Wie gesagt, wenn ich den Inhalt von der Do() Methode in die main einfüge, klappt es.

    Die Klassen sind im Anhang mit Kommentaren zu lesen.

    Kann mir einer auf die Sprünge helfen?
     

    Attached Files:

  2. daboom

    daboom Megabyte

    Du hast, glaub ich, den Sinn von Header- und Implementierungsdatei nicht ganz verstanden... ;)

    Im Prinzip sollte es so sein:

    Die Header-Datei definiert lediglich eine Klasse ohne sie zu implementieren... Das heißt ein Header sollte nur aus Member- und Methodendeklarationen bestehen. Also schmeißt Du am besten alles aus dem Header, was nach dem schließenden "};" vom "class"-Block kommt und verschiebst es in die entsprechende .cpp-Datei.

    Wenn Du "Person" dann irgendwo benutzt, wie in der main.cpp, dann bindest Du aber nach wie vor nur den Header ein (also wie Du es jetzt schon richtig tust), der Linker erledigt dann den Rest schon korrekt.

    Wenn Die Do-Methode eine Membermethode von Person sein soll, müsste sie auch in der Klasse Person (also im Header) deklariert werden.
    Prinzipiell (so wie sie implementiert ist) müsste sie das aber nicht. Da wäre es wohl sinnvoller, die mit in die main.cpp zu übernehmen, so dass die beiden Person.xxx Dateien wirklich nur die Klasse Person definieren.
    Dabei musst Du allerdings drauf achten, dass Do vor main kommt, weil die ansonsten dort unbekannt ist.

    Eine andere Möglichkeit wäre es, noch eine main.h einzuführen oder die Do in der main.cpp als Prototype zu deklarieren, aber das führt jetzt sicherlich erstmal zu weit ;)
     
  3. noob222

    noob222 Byte

    Also ich verstehe nicht wie ich ein Objekt vom Typ Person erstellen und von diesem Typ auf die Do-Methode zugreifen kann. Meine Do-Methode hat ja keine Parameter, daher müsste ich doch auch ein Objekt Person ohne Parameterübergabe erstellen und von diesem aus irgendwie auf die Do-Methode zugreifen. Aber wie?

    Mit dem "." Operator kann ich ja auf die verschiedenen Methoden zugreifen wie z.b. SetAge(), GetAge()... Aber es erscheint keine "Do()"-Methode, warum?

    Ist es überhaupt richtig die Do-Methode als "bool" du deklarieren und in dieser Methode das Alter und die Größen einlesen?

    Mein Code würde dann jetzt mal so aussehen (nachdem ich mal deine Punkte hab einfliessen lassen)

    Person.h
    Code:
    class Person{
    public: 
    	Person(int groesse, int alter);
    	~Person();
    	int GetGroesse() const;
    	void SetGroesse(int groesse);
    	int GetAge() const;
    	void SetAge(int alter);
    	bool Do();
    private:
    	int size;
    	int age;
    };
    
    
    Person.cpp
    Code:
    #include "Person.h"
    #include <iostream>
    #include <stdio.h>
    using namespace std;
    
    Person::Person(int groesse, int alter){
    		size=groesse;
    		age=alter;
    }
    
    Person::~Person(){
    }
    
    int Person::GetAge() const{
    	return age;
    }
    int Person::GetGroesse() const{
    	return size;
    }
    void Person::SetGroesse(int groesse){
    	size=groesse;
    }
    void Person::SetAge(int alter){
    	age=alter;
    }
    bool Person::Do(){
    		int groesse, alter;
    		cout << "Bitte geben sie die Gr&#246;sse ein: ";
    		cin >> groesse;
    		cout << "\n Bitte geben sie das Alter ein: ";
    		cin >> alter;
    		Person Mensch(groesse,alter);
    		Mensch.SetGroesse(groesse);
    		cout << "Die Person ist : " << Mensch.GetGroesse() << " cm gross \n";
    		Mensch.SetAge(alter);
    		cout << "Die Person ist " << Mensch.GetAge() << " Jahre alt \n";
    		return true;
    }
    
    main.cpp

    Code:
    #include <stdio.h>
    #include <iostream>
    class Person;
    using namespace std;
    
    
    int main(){
    	Person Test;
    	Test.Do();
    	return 0;
    }
    
    

    PS: Wie gesagt w&#252;rde es funktionieren wenn ich die Do-Methode an allen entsprechenden Stellen weglasse und den Inhalt in der Main einf&#252;ge, dann l&#228;uft auch mein Programm fehlerfrei. Wie gesagt m&#246;chte ich in der main nicht so viele Sachen stehen haben. Daher habe ich an eine extra Methode wei die "Do-Methode" gedacht, so dass ich in der main mit hoffentlich 1-2 Zeilen diese Do-Methode ausf&#252;hren kann.

    Code:
    #include <stdio.h>
    #include <iostream>
    #include "Person.h"
    class Person;
    using namespace std;
    
    
    int main(){
    	int groesse, alter;
    	cout << "Bitte geben sie die Gr&#246;sse ein: ";
    	cin >> groesse;
    	cout << "\n Bitte geben sie das Alter ein: ";
    	cin >> alter;
    	Person Mensch(groesse,alter);
    	Mensch.SetGroesse(groesse);
    	cout << "Die Person ist : " << Mensch.GetGroesse() << " cm gross \n";
    	Mensch.SetAge(alter);
    	cout << "Die Person ist " << Mensch.GetAge() << " Jahre alt \n";
    	return 0;
    }
    
     
    Last edited: Sep 7, 2009
  4. daboom

    daboom Megabyte

    OK, dann sollte man sich mal genau im Klaren dar&#252;ber sein, was welche Methode machen soll...

    Du kannst nicht einfach eine unbekannte (weil nicht im Header deklarierte) Do-Methode in die Person.cpp reinschreiben. Die kennt dann n&#228;mlich au&#223;erhalb keiner. Man kennt ja nur das, was im Header steht. Ich hab ja oben schon geschrieben, dass Du die Do-Methode mit in die main.cpp schreiben sollst.

    Dann bleibt die Frage, was diese Methode nun eigentlich genau tun soll...

    Ich fasse mal zusammen, was Du dort alles (wenn auch teilweise doppelt) machst:

    - Gr&#246;&#223;e und Age aus der Konsole einlesen
    - Diese Werte einer Person-Instanz mitgeben (hier &#252;brigens doppelt, einmal im Konstruktor und dann nochmals &#252;ber die Setter)
    - Die gerade gesetzten Werte wieder &#252;ber Getter abfragen und auf der Konsole ausgeben

    Man k&#246;nnte das Ganze halbwegs sinnvoll aufteilen, in dem man eine statische Methode "readPerson()" und eine Member-Methode "writePerson()" in die Klasse Person einf&#252;gt.

    Dann w&#252;rdest Du in der main ungef&#228;hr folgendes machen:

    PHP:
    int main() {
      
    PersonPerson::readPerson();
      
    p.writePerson();
    }

    Daf&#252;r bekommt dann Person.h folgendes:

    PHP:
    class Person {
      public:
        ...
        
    void writePerson();

        static 
    Person readPerson();
      ...
    }
    Wobei die Implementierung dann so auss&#228;he: (Also zus&#228;tzlich in der Person.cpp)

    PHP:
    void Person::writePerson() {
      
    cout << "Die Person ist " << size " cm gro&#223;.";
      
    cout << "Und " << age << " Jahre alt." << endl;
    }

    Person readPerson() {
      
    int altergroesse// Hier mal deutsch, nur um Verwechslungen mit den Membervariablen auszuschlie&#223;en ;)

      
    cout << "Bitte geben sie die Gr&#246;&#223;e an";
      
    cin >> groesse;
      
    cout << "Bitte geben sie das Alter an";
      
    cin >> alter;

      
    Person rueckgabe(groessealter);

      return (
    rueckgabe);
    }
    Ich hoffe, Du verstehst ein bischen, worauf ich hinaus will... ;)
     
  5. noob222

    noob222 Byte

    Also da hast du schon recht, das ich teilweise alles doppelt gemacht habe :-)

    habe mal mein code um die Methoden WritePerson() und ReadPerson() angepasst.

    Bekomme jetzt beim Kompilieren folgende Fehlermeldung:

    Code:
    1>main.obj : error LNK2001: Nicht aufgelöstes externes Symbol ""public: static class Person __cdecl Person::ReadPerson(void)" (?ReadPerson@Person@@SA?AV1@XZ)".
    Meine erste Frage: Wozu hast du den "&" Operator benutzt? Der wird doch bei Pointern eingesetzt und ich arbeite ja nicht mit Pointern oder sehe ich das falsch? Zudem müsste ich doch auch die Variablen "&size, &age" entsprechend anspassen!?

    Meine zweite Frage: Die Fehlermeldung LNK2001 bedeut ja, dass ein Verweis auf eine Methode/Variable gemacht wird, dass der Linke in den Objektdateien nicht finden kann. Also die Methode ReadPerson(), findet er ja sobald ich schon "Person::" eingebe.
    Was bedeutet das jetzt?

    Vielen Dank
     
  6. daboom

    daboom Megabyte

    Zur ersten Frage:

    Der &-Operator hat zwei Aufgaben:

    1. Wie Du schon gesagt hast, die Adresse einer / den Pointer auf eine Variable ermitteln. Bsp:

    PHP:
    int i 1;
    intptr = &i;
    Hier steckt in "ptr" jetzt ein Pointer auf "i". Dar&#252;ber kann man per *-Operator wieder an den Wert (in diesem Falle "1") drankommen, also z.B.

    PHP:
    int j = *ptr;
    2. Bei der Deklaration von Referenz-Variablen. Hier also eigentlich kein Operator sondern ein deklaratives Zeichen.
    Bsp:

    PHP:
    int i 1;
    intref i;
    Hier ist "ref" fast gleichbedeutend mit "ptr" im obigen Beispiel, mit der Ausnahme, dass man "ref" wie die eigentliche Variable, die es referenziert (also "i") verwenden kann, indem man beispielsweise schreibt:

    PHP:
    int j ref// j w&#228;re dann hier "1"
    ref 2// Hier w&#228;ren "ref" und "i" dann "1"
    Du kannst in meinem Beispielcode das "&" auch weglassen, funktioniert genauso. Ist blo&#223; etwas aufw&#228;ndiger, da an der Stelle das "Person"-Objekt bei der R&#252;ckgabe kopiert wird. Mit dem "&" wird der Variablen "p" einfach direkt eine Referenz auf das zur&#252;ckgegebene Person-Objekt zugewiesen. Ohne wird "p" nochmals eine Kopie zugewiesen.


    Zur zweiten Frage:

    Dass (Du meintest vermutlich Deine IDE) bei "Person::" die entsprechende Methode gefunden wird, hei&#223;t nur, dass sie im Header deklariert ist, aber noch lange nicht, dass der Linker zum Schluss auch deren Definition (also die Implementierung im cpp-File) findet.
    Am besten, Du postest nochmal die beiden Person-Quelldateien, der Fehler liegt sicherlich in der cpp.
     
Thread Status:
Not open for further replies.

Share This Page