Anfänger(!): Konstruktor?
-
Ich habe folgende Klassen:
#include <string> using namespace std; class Cell { private: Cell* next; Cell* previous; public: Cell() { } virtual string display() const = 0; }; class LinkedList { private: Cell* highest; Cell* lowest; public: LinkedList() { } void insert(int customer_number, string customer_name, string customer_street, string customer_postcode, string customer_city, string customer_country) { } void deletion(int customer_number) { } void retrieve(int customer_number) { } string display() { } }; class BaseEl : public Cell { private: int customer_number; string customer_name; public: BaseEl(int number, string name) { customer_number = number; customer_name = name; } string display() const { return "test"; } }; class ListEl : public BaseEl { private: string customer_street; string customer_postcode; string customer_city; string customer_country; public: ListEl(string street, string postcode, string city, string country) { customer_street = street; customer_postcode = postcode; customer_city = city; customer_country = country; } string get_street() const { return customer_street; } string get_postcode() const { return customer_postcode; } string get_city() const { return customer_city; } string get_country() const { return customer_country; } string display() const { string return_value; return_value = "Strasse: " + get_street() + "\nPostleitzahl: " + get_postcode() + "\nStadt: " + get_city() + "\nLand: " + get_country() + "\n"; return return_value; } };
Merkwürdigerweise funktioniert der Konstruktor für BaseEl nicht, ich kriege beim Debuggen immer den Fehler 'BaseEl' : no appropriate default constructor available
-
Du hast auch keinen Defaultkonstruktor für BaseEl erzeugt! Sobald du einen eigenen Konstruktor erstellst, darf der Compiler keinen Defaultkonstruktor mehr erzeugen, somit musst du das selbst machen !
-
Das geht trotzdem nicht. Ich habe den Code jetzt so (hoffe, das mit dem Destruktor ist korrekt so):
#include <string> using namespace std; class Cell { private: Cell* next; Cell* previous; public: virtual ~Cell(); virtual string display() const = 0; }; class LinkedList { private: Cell* highest; Cell* lowest; public: LinkedList() { } void insert(int customer_number, string customer_name, string customer_street, string customer_postcode, string customer_city, string customer_country) { } void deletion(int customer_number) { } void retrieve(int customer_number) { } string display() { } }; class BaseEl : public Cell { private: int customer_number; string customer_name; public: BaseEl(int number, string name) { customer_number = number; customer_name = name; } ~BaseEl() { } string display() const { return "test"; } }; class ListEl : public BaseEl { private: string customer_street; string customer_postcode; string customer_city; string customer_country; public: ListEl(string street, string postcode, string city, string country) { customer_street = street; customer_postcode = postcode; customer_city = city; customer_country = country; } ~ListEl() { } string get_street() const { return customer_street; } string get_postcode() const { return customer_postcode; } string get_city() const { return customer_city; } string get_country() const { return customer_country; } string display() const { string return_value; return_value = "Strasse: " + get_street() + "\nPostleitzahl: " + get_postcode() + "\nStadt: " + get_city() + "\nLand: " + get_country() + "\n"; return return_value; } };
-
Merkwürdigerweise funktioniert der Konstruktor für BaseEl nicht
Das möchte ich bezweifeln. Das Problem scheint mir viel mehr zu sein, dass du ihn nicht aufrufst.
ich kriege beim Debuggen immer den Fehler 'BaseEl' : no appropriate default constructor available
Wie schaffst du es, dass dieser Fehler erst beim Debuggen kommt?
Ich gehe mal davon aus, dass du irgendwo ein Objekt der Klasse ListEl erzeugst.
Etwa so:ListEl einObjekt("meine Strasse", "12345", "meine Stadt", "mein Land");
Das Problem ist nun folgendes:
In der oberen Zeile wird der Konstruktor von ListEl aufgerufen. Da diese Klasse aber von BaseEl erbt, muss zuvor ein Konstruktor dieser Basisklasse aufgerufen werden. Da du nicht angegeben hast welcher Basisklassen-Konstruktor aufgerufen werden soll, ruft der Compiler automatisch den Standardkonstruktor auf (also einen Konstruktor der sich ohne Argumente aufrufen lässt).
Schaut man nun in die Basisklasse BaseEl, stellt man fest, dass dort kein solcher Konstruktor existiert. Da BaseEl aber einen anderen benutzerdefinierten Konstruktor hat, verzichtet der Compiler darauf einen Standardkonstruktor automatisch zu erzeugen. Es gibt also keinen Standardctor und daher kommt es zu der beschriebenen Fehlermeldung.Lösung: Du musst entweder im ListEl Ctor den aufzurufenden Basisklassenctor angeben. Oder der Basisklasse einen Standardkonstruktor spendieren.
Ersteres machst du in der Elementinitialisierungsliste. Nun hast du in deinem Code aber das Problem, dass der BaseEl-Ctor eine Nummer und einen Namen erwartet. Beides Dinge, die du nicht zur Verfügung hast. Es stimmt also etwas mit deinem Design nicht. Hier erstmal die syntaktische Lösung:// Der Doppelpunkt nach der Parameterliste leitet // die Elementinitialisierungsliste ein. // Hier kannst du eigene Member initialisieren und // Argumente an aufzurufende Basisklassenkonstruktoren übergeben ListEl::ListEl(string street, string postcode, string city, string country) : BaseEl(22, "Ein Name") { customer_street = street; customer_postcode = postcode; customer_city = city; customer_country = country; }
Das lässt sich aber noch verbessern: (http://www.c-plusplus.net/ubb/cgi-bin/ultimatebb.cgi?ubb=get_topic&f=25&t=000014)
// Der Doppelpunkt nach der Parameterliste leitet // die Elementinitialisierungsliste ein. // Hier kannst du eigene Member initialisieren und // Argumente an aufzurufende Basisklassenkonstruktoren übergeben ListEl::ListEl(string street, string postcode, string city, string country) : BaseEl(22, "Ein Name") , customer_street(street) , customer_postcode(postcode) , customer_city(city) , customer_country(country) {}
-
Kann ich nicht sowas machen:
ListEl(int number, string name, string street, string postcode, string city, string country) { BaseEl(number, name); customer_street = street; customer_postcode = postcode; customer_city = city; customer_country = country; }
Meine Idee ist hier, dass ich ja für ein ListEl auch eine Nummer und einen Namen habe (ist ja vererbt). Die könnte ich dich im ListEl- Konstruktor gleich intitialisieren oder?
[ Dieser Beitrag wurde am 03.05.2003 um 14:13 Uhr von marcoow editiert. ]
-
Ich habe jetzt selbst schon was hingekriegt. Das Problem ist nur, dass in der viertletzten Zeile (return_value = ...) beim Debuggen der Fehler kommt
error C2110: cannot add two pointersCode jetzt:
#include <string> using namespace std; class Cell { private: Cell* next; Cell* previous; public: //virtual ~Cell(); virtual string display() const = 0; }; class LinkedList { private: Cell* highest; Cell* lowest; public: LinkedList() { } void insert(int customer_number, string customer_name, string customer_street, string customer_postcode, string customer_city, string customer_country) { } void deletion(int customer_number) { } void retrieve(int customer_number) { } string display() { } }; class BaseEl : public Cell { private: int customer_number; string customer_name; public: BaseEl(int number, string name) { customer_number = number; customer_name = name; } ~BaseEl() { } int get_number() const { return customer_number; } string get_name() const { return customer_name; } string display() const { return "test"; } }; class ListEl : public BaseEl { private: string customer_street; string customer_postcode; string customer_city; string customer_country; public: ListEl(int number, string name, string street, string postcode, string city, string country) : BaseEl(number, name) { customer_street = street; customer_postcode = postcode; customer_city = city; customer_country = country; } ~ListEl() { } int get_number() const { return BaseEl::get_number(); } string get_name() const { return BaseEl::get_name(); } string get_street() const { return customer_street; } string get_postcode() const { return customer_postcode; } string get_city() const { return customer_city; } string get_country() const { return customer_country; } string display() const { string return_value; return_value = "Nummer: " + get_number() + "\nName: " + get_name() + "\nStrasse: " + get_street() + "\nPostleitzahl: " + get_postcode() + "\nStadt: " + get_city() + "\nLand: " + get_country() + "\n"; return return_value; } };