const-Referenzen in Klassen



  • Hallo Forum,

    habe einen Text aus einem C++Kurs, der nur die Hälfte des Programms darstellt.
    ich kriege es nicht so ganz hin das zu vervollständigen, vielleicht kann hier einer helfen.
    Hier ist mein Code:

    #include <iostream>
    #include <string>
    using namespace std;
    
    class Student
    {
    private:
       string vorname;
       string name;
       string strasse;
       string hausnummer;
       string postleitzahl;
       string ort;
    
       string hochschulort;
       string hochschule;
       string matrikelnummer;
       string semesteranzahl;
    
    public:
       string getName() const
       {
          return name;
       };
       string getVorname () const
       {
          return vorname;
       };
       string getStrasse ()
       {
    	   return strasse; 
       };
       string getHausnummer()
       {
    	   return hausnummer;
       };
       string getPostleitzahl()
       {
    	   return postleitzahl;
       };
       string getOrt()
       {
    	   return ort;
       };
       string getHochschulort()
       {
    	   return hochschulort;
       };
       string getHochschule()
       {
    	   return hochschule;
       };
       string getMatrikelnummer()
       {
    	   return matrikelnummer;
       };
       string getSemesteranzahl()
       {
    	   return semesteranzahl;
       }
    };
    void printStudent(const Student &student)
    {
       cout<<student.getVorname()<<' '<<student.getName()<<endl;
    };
    void printList()
    {
    int ANZAHL_STUDENTEN=1;
    
      for(int i=0;i<ANZAHL_STUDENTEN;i=i+1)
          printStudent(student[i]);
    };
    void main()
    {
    	printList();
    };
    

    Die Fehler die ich bekomme lauten:

    ...übungen\Lektion38\const_Referenzen\main.cpp(71) : error C2065: 'student' : nichtdeklarierter Bezeichner
    ...übungen\Lektion38\const_Referenzen\main.cpp(71) : error C2109: Index benoetigt ein Feld oder einen Zeigertyp
    ...übungen\Lektion38\const_Referenzen\main.cpp(71) : error C2664: 'printStudent' : Konvertierung des Parameters 1 von 'int' in 'const class Student &' nicht moeglich
    Ursache: Konvertierung von 'int' in 'const class Student' nicht moeglich
    Quelltyp konnte von keinem Konstruktor angenommen werden, oder die Ueberladungsaufloesung des Konstruktors ist mehrdeutig
    Fehler beim Ausführen von cl.exe.

    Hier die Ausführungen des Kurses
    Zitat-Anfang:

    const-Referenzen
    Referenz-Parameter werden auch gerne dafür verwandt, um Funktionaufrufe schneller zu machen. Stellen Sie sich vor, Sie haben eine Klasse, die viele Attribute enthält, z.B.

    class Student
    {
    private:
       string vorname;
       string name;
       string strasse;
       string hausnummer;
       string postleitzahl;
       string ort;
    
       string hochschulort;
       string hochschule;
       string matrikelnummer;
       string semesteranzahl;
       [...]
    public:
       string getName()
       {
          return name;
       };
       string getVorname ()
       {
          return vorname;
       };
       [...]
    };
    

    und dazu eine Funktion, die aus einem Array voller Studenten eine Liste aller Namen ausdruckt. Weil es übersichtlicher ist, wird diese Funktion in zwei kleinere Funktionen zerlegt:

    void printStudent(Student student)
    {
       cout<<student.getVorname()<<' '<<student.getName()<<endl;
    };
    void printList()
    {
       for(int i=0;i<ANZAHL_STUDENTEN;i=i+1)
          printStudent(student[i]);
    };
    

    Weil die Übergabe des Studenten in der Funktion printStudent call by value ist, wird jedesmal eine komplette Kopie des Studenten angelegt und in der lokalen Variablen student gespeichert. Weil die Klasse Student recht viele Attribute besitzt, kostet das viel Rechenzeit. Deshalb ist es üblich, zu diesem Zweck einen Referenz-Parameter zu verwenden(Referenz-Parameter, Performance).

    void printStudent(Student &student)

    Die Übergabe ist jetzt erheblich schneller, weil nur ein (als Referenz getarnter) Zeiger auf das zu übergebende Objekt übergeben wird.

    Doch mit dieser Variante wäre nie sichergestellt, daß die Funktion printStudent nicht doch Veränderungen am übergebenen Objekt vornimmt. Um den Geschwindigkeitsvorteil der Referenz-Übergabe mit dem Sicherheitsvorteil der Wert-Übergabe kombinieren zu können, gibt es die Übergabe als const-Referenz.

    void printStudent(const Student &student)

    Ab jetzt wehrt der Compiler alle Versuche ab, innerhalb der printStudent-Funktion Änderungen am übergebenen Objekt vorzunehmen. Innerhalb dieser Funktion ist die Variable student eine Konstante.

    Zitat-Ende:

    /edit: sfds



  • 1. C++ unterscheidet zwischen student und Student, damit wäre der erste Fehler schonmal erklärt.

    2. Kann ich so nichts dazu sagen, müsste ich Quellcode sehen.

    3.Du scheinst einen int-Parameter übergeben zu haben (vielleicht hat dein Compiler das argument automatisch umgewandelt -> kontrollieren).

    mfg
    Glamdring



  • Hi,

    das ist der Quellcode und das was im Kurstext steht.

    Irgendwie steht hier aber im Kurstext was von einem Array voller Studenten

    zitat:

    und dazu eine Funktion, die aus einem Array voller Studenten eine Liste aller Namen ausdruckt. Weil es übersichtlicher ist, wird diese Funktion in zwei kleinere Funktionen zerlegt:

    [code]
    void printStudent(Student student) 
    { 
    cout<<student.getVorname()<<' '<<student.getName()<<endl; 
    }; 
    void printList() 
    { 
    for(int i=0;i<ANZAHL_STUDENTEN;i=i+1) 
    printStudent(student[i]); 
    }; 
    [/code]
    

    Zitat Ende

    Wo ist das Array ? ich habe unter printlist die Variable int ANZAHL_STUDENTEN=1; angelegt, damit ich dort erstmal einen Wert hatte, aber das kann ja so nicht richtig sein, oder ?

    Nachdem ich jetzt printStudent(Student[i]); also groß geschrieben habe, bekomme ich nur noch einen Fehler:

    ...übungen\Lektion38\const_Referenzen\main.cpp(71) : error C2275: "Student" : Ungültige Verwendung dieses Typs als Ausdruck
    ...übungen\Lektion38\const_Referenzen\main.cpp(6) : Siehe Deklaration von 'Student'
    Fehler beim Ausführen von cl.exe.

    der Pfeil springt dann oben an die erste Klammer der Klasse.



  • Erst einmal etwas prinzipielles zur Nutzung des Forums.
    Da es hier nicht selten vorkommt das jemand Code postet gibt es hier exta Code-Tags

    [cpp]
    

    und

    [/cpp]
    

    die du vor und nach deinen Code setzen solltest, was auch über die Buttens unter dem Eingabefeld machen kannst. Da gibt es auch noch mehr, schau es dir am besten mal an.
    Dann solltest du deinen Code auch gescheit einrücken (formatieren). Und in die Zeilen wo der Fehler auftritt einen Komentar einfügen, damit man auch weiß wo er auftritt.

    Jetzt zur Sache.
    ANZAHL_STUDENTEN würde ich irgendwo als Makro definieren:

    #define ANZAHL_STUDENTEN 5
    

    S204 schrieb:

    Wo ist das Array ?

    Ja, das ist hier die Frage. Das ist nämlich genau das was der Compiler vermisst. ein Student Array namens student. Das muß schon irgendwo angelegt werden.

    void printList()
    {
    	Student student[ANZAHL_STUDENTEN];
    	for(int i=0;i<ANZAHL_STUDENTEN;i++/* i=i+1 */)
    		printStudent(student[i]);
    };
    

    So würde es gehen, ist nur recht sinnlos, da die Studenten alle keine Namen haben. Du könntest es auch global anlegen und dann genauso nutzen. Wie und wo du es anlegen solltest fragst du am besten deinen Kursleiter.

    Gruß
    Entyl Sa



  • Entyl_Sa schrieb:

    ANZAHL_STUDENTEN würde ich irgendwo als Makro definieren:

    #define ANZAHL_STUDENTEN 5
    

    Wozu denn das wenns eine Konstante auch tut?



  • Weil

    for(int i=0;i<ANZAHL_STUDENTEN;i=i+1)
    

    diese Schleife vorgegeben war, und durchgehend großgeschriebene Bezeichner bei Makros verwendet werden.



  • Entyl_Sa schrieb:

    Weil

    for(int i=0;i<ANZAHL_STUDENTEN;i=i+1)
    

    diese Schleife vorgegeben war, und durchgehend großgeschriebene Bezeichner bei Makros verwendet werden.

    Nicht zwangsläufig.
    großbuchstaben geben Konstanten an - das sind leider oft markos, aber dafür gibt es meisstens keinen vernünftigen Grund.



  • Ja, es gibt verschiedene Argumente gegen die Existenzberechtigung von #define für Konstanten:

    - Typenunsicherheit
    - Debugging sehr erschwert:
    Man stelle sich jenes vor:

    #define BLA (100+200);
    

    Bspw. das würde jemand so schreiben, man kann sich bei sowas leichter mal verschreiben, als man denkt...
    Also man hat das geschrieben und ist auf die falsche Taste gekommen, aber mit der Maus schon über der anderen Datei und dann erfolgt der Doppelklick.
    Jetzt arbeitet man irgendwo damit weiter:

    int a = -9.5*(static_cast<int>(sqrt(15)+pow(BLA,9));
    

    Und jetzt zeigt er den Fehler in der Zeile mit a an.

    Das sind jetzt billige Beispiele (:)), aber so kann das wirklich gut mal passieren, und wenn es das tut, dann findet man den Fehler nicht...
    Gerade wenn es an kompliziertere Konstanten und Ausdrücke, in denen man das verwendet, geht, ist das Debugging dann DIE HÖLLE.🙄

    Keine Lust mehr Gründe aufzuzählen, ich empfehle: Scott Meyers - Effektiv C++ programmieren 😑

    MfG MAV



  • Hallo,

    ich habs geahnt, dass mein Geschreibsel nicht so ganz gut aussieht.

    Danke erst mal für die vielen Tipps, jetzt muss ich alles erst mal probieren, was ihr alle so geschrieben habt, damit ich es begreife.

    Das ist halt auch das Problem, wenn einer einen Online-Kurs ins Netz stellt und dann keine Zeit mehr für die Fragen hat.

    Für mich kam das Ganze auch so ein bisschen sinnlos vor, weil ich mir das Array zwar mit 20 50 oder 1000 lfd. Nummern (je Student eine) vorstellen kann, aber wie sieht das mit Name, Vorname usw. aus ? Bei SQL-Abfragen aus einer Datenbank bin ich noch lange nicht, erst mal will ich das Verwenden des C++-Codes erlernen und begreifen.

    Mario S204 🙄



  • #include <iostream>
    #include <string>
    using namespace std;
    
    class Student
    {
    private:
    	string vorname;
    	string name;
    	string strasse;
    	string hausnummer;
    	string postleitzahl;
    	string ort;
    
    	string hochschulort;
    	string hochschule;
    	string matrikelnummer;
    	string semesteranzahl;
    
    public:
    	Student(string vn,string n)
    		:vorname(vn),name(n)
    	{
    	}
    	string getName() const
    	{
    		return name;
    	};
    	string getVorname () const
    	{
    		return vorname;
    	};
    	string getStrasse ()
    	{
    		return strasse; 
    	};
    	string getHausnummer()
    	{
    		return hausnummer;
    	};
    	string getPostleitzahl()
    	{
    		return postleitzahl;
    	};
    	string getOrt()
    	{
    		return ort;
    	};
    	string getHochschulort()
    	{
    		return hochschulort;
    	};
    	string getHochschule()
    	{
    		return hochschule;
    	};
    	string getMatrikelnummer()
    	{
    		return matrikelnummer;
    	};
    	string getSemesteranzahl()
    	{
    		return semesteranzahl;
    	}
    };
    void printStudent(const Student &student)
    {
    	cout<<student.getVorname()<<' '<<student.getName()<<endl;
    };
    void printList(Student* studenten,int anzahl)
    {
    	for(int i=0;i<anzahl;i=i+1)
    		printStudent(studenten[i]);
    };
    void main()
    {
    	Student studenten[3]={Student("volkard","Henkel"),Student("hans","meiser"),Student("karl","dall")};
    	printList(studenten,3);
    };
    


  • Danke Volkard,

    so wird mir das schon viel klarer.

    Mario S204 🙂


Anmelden zum Antworten