Problem mit Konstruktor
-
Hallo,
ich habe irgendwie ein Problem mit meinem Konstruktor.
Ich habe die Oberklasse "Studenten" und die Unterklassen "Bachelor" und "Kosi"
Ich habe den Kosi Konstruktor
Kosi(name, firma)und den Bachelor Konstruktor
Bachelor(name)Inhaltlich sind beide identisch, bis auf die Tatsache, dass mein Kosi noch ein Firmenname gespeichert wird.
Nun zum Problem...
rufe ich auf
Kosi(name, firma)funktioniert alles einwandfrei.
Rufe ich allerdings
Bachelor(name)auf, dann wird irgendwie aus einem mir nicht nachvollziehbarem Grund
Bachelor(void)aufgerufen und somit wird nichts gespeichert.
Woran kann das liegen?
-
Vielleicht zeigst du mal deine Konstruktoren.
-
skizZ schrieb:
Rufe ich allerdings
Bachelor(name)auf, dann wird irgendwie aus einem mir nicht nachvollziehbarem Grund
Bachelor(void)aufgerufen und somit wird nichts gespeichert.
Zeig mal bitte den Konstruktoraufruf und die Signatur deiner Bachelor-Konstruktoren.
Den C++ kann keinen Konstruktor ohne Parameter aufrufen, wenn Parameter übergeben werden (Dies würde zu einem Compilerfehler führen).
-
Hi, ich poste einfach mal meinen Code...
Student.h
#pragma once #include <string> #include <vector> using namespace std; class Student { protected: vector<Student> Studenten; string Name; string Firmenname; int Matrikelnr; std::vector<int> Pruefung; public: Student(void); ~Student(void); Student(const string&); Student(const string&, const string&); friend class Kosi; friend class Bachelor; friend class Manager; };Student.cpp
#include "Student.h" extern Student s; Student::Student(void) { } Student::~Student(void) { } Student::Student(const string& Name) { this->Name = Name; } Student::Student(const string& Name, const string& Firmenname) { this->Name = Name; this->Firmenname = Firmenname; }Manager.cpp
#include "Manager.h" #include <iostream> #include <fstream> #include <string> extern Student s; Manager::Manager(void) { using namespace std; ifstream namen_dat( "Namen.dat", ios_base::binary ); const int N = 30; char name_carray[N+1]; name_carray[N] = 0; // sicheres End-Of-String while( namen_dat.read( name_carray, N ) ) // einen Datensatz lesen { string name = name_carray; int rnd=rand()%100; if(rnd > 29) Bachelor(name); if(rnd<30) { ifstream file; int zeile = 0; string fileName = "Firmen.txt"; file.open(fileName.c_str()); if(file) { string text; // Haupttext int zeile=rand()%37; int zeilen = 0; while(!file.eof()) { string txt; // Buffer getline(file, txt); text = txt + "\n"; zeilen++; if(zeile == zeilen) // gesuchte Zeile erreicht { Kosi(name, text); break; // Zeile gefunden, Einlesen abbrechen } } file.close(); } } } cout << s.Studenten.size(); } Manager::~Manager(void) { }Kosi.h
#pragma once #include "Student.h" #include <string> using namespace std; class Kosi : public Student { private: string Firmenname; public: Kosi(void); Kosi(const string&, const string&); ~Kosi(void); };Kosi.cpp
#include "Kosi.h" extern Student s; Kosi::Kosi(void) { } Kosi::~Kosi(void) { } Kosi::Kosi(const string& Name, const string& Firmenname) : Student(Name, Firmenname) { s.Studenten.push_back(*this); }Bachelor.h
#pragma once #include <string> #include "Student.h" using namespace std; class Bachelor : public Student { private: public: Bachelor(void); Bachelor(const string&); ~Bachelor(void); };Bachelor.cpp
#include "Bachelor.h" extern Student s; Bachelor::Bachelor(void) { } Bachelor::~Bachelor(void) { } Bachelor::Bachelor(const string& Name) : Student(Name) { s.Studenten.push_back(*this); }Ziel der Übung: Daten aus Dateien zufallsgesteuert zusammenfügen.
Mit dem Kosi funktioniert alles einwandfrei, nur mit dem Bachelor nicht.
-
Was passiert denn genau, wenn du den
Bachelor-Konstruktor aufrufst? Geh doch mal mit dem Debugger durch und schau, wo nicht das passiert, das du erwartest. Beim Code sind mir zudem einige Dinge aufgefallen:vector<Student> Studenten;Innerhalb der
Student-Klasse ist es eigentlich nicht sinnvoll, einen Container vom eigenen Typ zu haben. Vielleicht ein Container aus Zeigern, aber auch da stellt sich die Frage, ob der Student die anderen Studenten kennen soll.Die
friend-Deklarationen solltest du wenn möglich vermeiden, da dadurch das Prinzip der Kapselung und dem Schutz der Interna umgangen wird. Wenn duprotected-Member hast, können die abgeleiteten Klassen auch so zugreifen.extern Student s;Was ist mit dem? Wird der irgendwann definiert? Wieso überhaupt global?
Es gibt noch einige weitere Dinge, aber das sollte fürs erste reichen...
-
Hi,
alles klar, ich werde das alles mal beachten und nochmal durchgehen. Das mit dem Vektor ist natürlich wahr, den sollte ich in die Managerklasse packen

Also wenn ich den Bachelor aufrufe, ruft er Bachelor(void) auf

Ich melde mich morgen nochmal, falls ich es nicht schaffen sollte.
-
Probier dein Problem auf etwas einfacheres zu abstrahieren. Das hat viel zu viel drin, was nichts zur Sache tut. Und wenn du das erst mal draussen hast, wirst du den Fehler sicher selber finden.
btw:
- using namespace im Header i.d.R böse.
- Initialisierungsliste benutzen
-
Hi,
habe es nun hinbekommen.
allerdings habe ich nun noch eine Frage.In der Managerklasse habe ich folgenden Container in dem ich alle Studenten sammele
vector<Student*> Studenten;Die Unterklasse Kosi hat als Attribute Name und Firme.
Die Unterklasse Bachelor hat als Attribut nur den Namen.
Die Superklasse Student hat als Attribut nur den Namen.So, wie kann ich nun von der Managerklasse aus abfragen, welcher gespeicherte Student ein Kosi ist bzw den Firmennamen ausgeben?
Speichern tue ich sie auf diese Art
Studenten.push_back(new Kosi(name, firma)); Kosi::Kosi(const string& Name, const string& Firmenname) : Student(Name) { this->Firmenname = Firmenname; } Student::Student(const string& Name) { this->Name = Name; }
-
Das würde jetzt nur über einen dynamic_cast gehen.
alsoKosi* test = dynamic_cast<Kosi*>(Studenten[0]); if( test != 0) // dann ist es ein Kosi { }
-
Allerdings kann ich damit noch immer nicht auf das Kosi Attribut Firmenname zugreifen

-
skizZ schrieb:
Allerdings kann ich damit noch immer nicht auf das Kosi Attribut Firmenname zugreifen

Doch, kannst du, indem du den Zeiger dereferenzierst.