Problem mit vordefinierten Parametern/Attributen
-
Wurde sie ja eben nicht.
Hier mal alles:
DoubleLinkedList.h
#ifndef DOUBLELINKEDLIST_H_ #define DOUBLELINKEDLIST_H_ #include "DoubleLinkedListElement.h" #include <iostream> using namespace std; class DoubleLinkedList { friend class DoubleLinkedListElement; friend DoubleLinkedList operator+(const DoubleLinkedList&, const DoubleLinkedList&); private: unsigned int length; DoubleLinkedListElement* head; void init(); public: DoubleLinkedList(); DoubleLinkedList(const char** , unsigned int ,unsigned int ); //DoubleLinkedList(const char**, unsigned int); void push_back(const char*); void push_front(const char*); const char* pop_back(); const char* pop_front(); void insert(unsigned int,const char*); void addArray(const char*[] ,unsigned int ,unsigned int); void remove(unsigned int); unsigned int getLength() const; bool operator==(const DoubleLinkedList&) const; bool operator!=(const DoubleLinkedList&) const; DoubleLinkedList operator+=(const DoubleLinkedList&); const char* operator[](unsigned int) const; void print(); }; //#include "DoubleLinkedList.cpp" #endif /*DOUBLELINKEDLIST_H_*/DoubleLinkedList.cpp
#include "DoubleLinkedList.h" #include <cstring> DoubleLinkedList::DoubleLinkedList() { init(); } /* DoubleLinkedList::DoubleLinkedList(const char* elements[] , unsigned int count) { init(); addArray(elements,count,0); }*/ DoubleLinkedList::DoubleLinkedList(const char* elements[], unsigned int count, unsigned int offset=10) { init(); addArray(elements,count,offset); } void DoubleLinkedList::init() { //Liste auf Ursprung setzen head = NULL; length = 0; } void DoubleLinkedList::push_back(const char* element) { //Wenn Liste leer... if(!head) { //...Element als head einfügen head = new DoubleLinkedListElement(element,NULL,NULL); head->prev = head; head->next = head; } //Ansonsten... else { //...ans Ende anhängen (vor dem head einfügen) DoubleLinkedListElement* dlle = new DoubleLinkedListElement(element,head->prev,head); dlle->prev->next = dlle; dlle->next->prev = dlle; } //Zähler erhöhen length++; } void DoubleLinkedList::push_front(const char* element) { //Element am Ende anhängen (vor dem head) this->push_back(element); //head auf das bisher letzte Element der Liste setzen head = head->prev; } const char* DoubleLinkedList::pop_back() { //Liste ist leer if(!head) return NULL; //Zeiger auf das letzte Element der Liste DoubleLinkedListElement* dlle = head->prev; //Das einzige Element soll entfernt werden if(dlle == head && dlle->next == head) head = NULL; //Wert auslesen const char* value = dlle->value; //Zeiger der umgebenden Elemente ändern dlle->prev->next = dlle->next; dlle->next->prev = dlle->prev; //Element löschen delete dlle; //Zähler dekrementieren length--; //Wert zurückgeben return value; } const char* DoubleLinkedList::pop_front() { if(!head) return NULL; //head auf das 2. Element der Liste setzen head = head->next; //Letztes Element der Liste entfernen (vorheriger Head) und Wert zurückgeben return pop_back(); } void DoubleLinkedList::addArray(const char* elements[], unsigned int count, unsigned int offset=0) { //Elemente einfügen for(unsigned int i = offset; i < count+offset; i++) { push_back(elements[i]); } } void DoubleLinkedList::insert(unsigned int position,const char* element) { //Wenn Liste leer oder Position zu groß... if(!head || position > length) { //...am Ende anhängen push_back(element); } //Ansonsten... else { //...An entsprechender Position einsetzen DoubleLinkedListElement* posElement = head; for(unsigned int i = 0; i < position; i++) posElement = posElement->next; DoubleLinkedListElement* dlle = new DoubleLinkedListElement(element,posElement->prev,posElement); dlle->prev->next = dlle; dlle->next->prev = dlle; length++; } } void DoubleLinkedList::remove(unsigned int position) { //Liste ist leer, also nix tun if(!head)return; //Position == 0 else if(position == 0) { //...erstes Element wird entfernt pop_front(); } //Position ist zu groß... else if(position > length-1) { //...letztes Element wird entfernt pop_back(); } //Ansonsten else { //...Position ermitteln DoubleLinkedListElement* dlle = head; for(unsigned int i = 0; i < position; i++)dlle=dlle->next; //...Zeiger der Nachbarelemente tauschen dlle->prev->next = dlle->next; dlle->next->prev = dlle->prev; //Element löschen delete dlle; //Zeiger dekrementieren length--; } } unsigned int DoubleLinkedList::getLength() const { //Länge der Liste zurückgeben return length; } bool DoubleLinkedList::operator==(const DoubleLinkedList& list) const { DoubleLinkedList self(*this); unsigned int llength = list.getLength(); //Wenn die Länge ungleich ist, sind die Listen nicht gleich if(length != llength) return false; //Elementweises vergleichen for(unsigned int i = 0; i < length; i++) { //Wenn die Elemente nicht gleich sind, sind die Listen nicht gleich if(strcmp(self[i],list[i]))return false; } //Listen sind gleich return true; } bool DoubleLinkedList::operator!=(const DoubleLinkedList& list) const { return !operator ==(list); } DoubleLinkedList operator+(const DoubleLinkedList& list1 ,const DoubleLinkedList& list2) { DoubleLinkedList tmp; //1. Liste zur tmp-liste hinzufügen tmp+=list1; //2. Liste zur tmp-liste hinzufügen tmp+=list2; //tmp-liste zurückgeben return tmp; } DoubleLinkedList DoubleLinkedList::operator+=(const DoubleLinkedList& list) { //Elementweises anhängen der Elemente for(unsigned int i = 0; i < list.getLength(); i++) { this->push_back(list[i]); } //Gibt sich selbst zurück return *this; } const char* DoubleLinkedList::operator[](unsigned int position) const { //Liste leer oder Position zu groß if(!head || position >= length)return NULL; //Element an der gewünschten Position suchen DoubleLinkedListElement* dlle = head; for(unsigned int i = 0; i < position; i++) dlle=dlle->next; //Wert des Elements zurückgeben return dlle->value; } void DoubleLinkedList::print() { //Alle elemente ausgeben DoubleLinkedList self = DoubleLinkedList(*this); cout << "-----------------------\n" << "length: " << length << "\n" << "-----------------------" << endl; for(unsigned int i = 0; i < length; i++) { cout << i << ": " << self[i] << endl; } cout << "-----------------------" << endl; }@Nexus: War wohl blind...Danke

-
Du musst den Standardparameter im Header angeben. Wenn der Compiler die Test.cpp kompiliert, weiß er ja nicht, dass du in einer gänzlich anderen .cpp einen Standardwert für den letzten Parameter angegeben hast. Er sieht ja nur den Header, in dem 3 Parameter verlangt werden und es keinen Standardwert gibt, so dass man mit 2 Parametern aufrufen könnte.
-
Habs jetzt mal so geändert:
#ifndef DOUBLELINKEDLIST_H_ #define DOUBLELINKEDLIST_H_ #include "DoubleLinkedListElement.h" #include <iostream> using namespace std; class DoubleLinkedList { friend class DoubleLinkedListElement; friend DoubleLinkedList operator+(const DoubleLinkedList&, const DoubleLinkedList&); private: unsigned int length; DoubleLinkedListElement* head; void init(); public: DoubleLinkedList(); DoubleLinkedList(const char**, unsigned int ,unsigned int ); DoubleLinkedList(const char**, unsigned int); void push_back(const char*); void push_front(const char*); const char* pop_back(); const char* pop_front(); void insert(unsigned int,const char*); void addArray(const char*[] ,unsigned int ,unsigned int); void remove(unsigned int); unsigned int getLength() const; bool operator==(const DoubleLinkedList&) const; bool operator!=(const DoubleLinkedList&) const; DoubleLinkedList operator+=(const DoubleLinkedList&); const char* operator[](unsigned int) const; void print(); }; //#include "DoubleLinkedList.cpp" #endif /*DOUBLELINKEDLIST_H_*/aber trotzdem:
make -k all /usr/bin/g++ -Wall -o DoubleLinkedList Test.o DoubleLinkedList.o DoubleLinkedListElement.o Test.o: In function `main': Test.cpp:(.text+0xc9): undefined reference to `DoubleLinkedList::DoubleLinkedList(char const**, unsigned int)' collect2: ld gab 1 als Ende-Status zurück make: *** [all] Fehler 1
-
Ja, jetzt hast du DoubleLinkedList::DoubleLinkedList(char const**, unsigned int) hinzugefügt, also hat der Compiler nix zu meckern wenn er test.cpp kompiliert, aber wo hast du denn DoubleLinkedList::DoubleLinkedList(char const**, unsigned int) implementiert? Daran knabbert der Linker jetzt.
Das einzige was ich die ganze Zeit doch sagen möchte ist, du hättest im HEADER stehen haben müssen:
DoubleLinkedList(const char**, unsigned int ,unsigned int someval = 5 );
Dann hättest du auch keine zusätzliche Funktion deklarieren müssen, weil der Compiler dann, während er test.cpp kompiliert, weiß, dass der letzte Parameter einen default-Wert besitzt und man die Funktion somit auch mit 2 Parametern aufrufen kann.
Und überhaupt, im Header solltest du allen Parametern einen Namen geben, das macht es demjenigen einfacher, die Bibliothek zu benutzen, wenn er sich nur den Header (= Die Schnittstelle zu den Objekten) anschaut.
-
Dann kann ich das also nicht weglassen?
Ich dachte, dass das der Sinn der vordefinierten Parameter ist.
Muss ich also den Konstruktor komplett anlegen, oder kann ich den Aufruf umleiten?
-
Siehe oben, hab das nachträglich nochmal etwas verdeutlicht.
-
Also was es mitzunehmen gilt: Der Compiler sieht immer nur eine einzige .cpp datei und alles was diese datei #include'd hat. Der hat keine Ahnung davon, dass eine andere .cpp datei irgendwelche Standardparameter definiert. Der Linker ist dann dafür zuständig die ganzen Symbole zwischen mehreren "Units" (=.o-Dateien) aufzulösen und den Implementierungen (= Dem Maschinencode) zuzuordnen. Mal etwas vereinfacht ausgedrückt. Und da Standardparameter etwas sind, das auf Compilerebene wirkt, ergibt sich dein beobachtetes Problem.
-
OK:
1. Hab ich jetzt alle Parameter mit Namen angegeben.
2. Der Konstruktor lautet jetzt so:DoubleLinkedList(const char* elements[], unsigned int count,unsigned int offest = 0);Das hatte ich auch schonmal, aber es klappt nicht:
make -k all /usr/bin/g++ -Wall -c DoubleLinkedList.cpp DoubleLinkedList.cpp:15: Fehler: Standardargument für Parameter 3 von »DoubleLinkedList::DoubleLinkedList(const char**, unsigned int, unsigned int)« angegeben DoubleLinkedList.h:20: Fehler: nach vorheriger Spezifikation in »DoubleLinkedList::DoubleLinkedList(const char**, unsigned int, unsigned int)« make: *** [DoubleLinkedList.o] Fehler 1 make: Das Target »all« wurde wegen Fehlern nicht aktualisiert
-
Naja, jetzt kannst du ja (rein logisch gesehen) und musst (dem C++-Standard nach) die Spezifikation eines Standardwertes für den 3. Parameter in der Implementierung weglassen.
-
Ariol schrieb:
make -k all ... DoubleLinkedList.cpp:15: Fehler: Standardargument für Parameter 3 von »DoubleLinkedList::DoubleLinkedList(const char**, unsigned int, unsigned int)« angegeben ...Lies mal bitte alle Postings nochmal durch.
Standardparameter müssen ausschließlich in der Deklaration angegeben werden. Der Compiler sagt aber das du in der "DoubleLinkedList.cpp" (und ich wette dort in der Definition) einen Standardwert angegeben hast.
-
Sorry, falsche Ausgabe gepostet:
hier die richtige:make -k all /usr/bin/g++ -Wall -o DoubleLinkedList Test.o DoubleLinkedList.o DoubleLinkedListElement.o Test.o: In function `main': Test.cpp:(.text+0xc9): undefined reference to `DoubleLinkedList::DoubleLinkedList(char const**, unsigned int)' collect2: ld gab 1 als Ende-Status zurück make: *** [all] Fehler 1.............
Ok, der Fehler war ein fehlendes "make clean".
Mann, das hätte ich schon vorgestern haben können.
Vielen Dank für eure Hilfe.
Jetzt klappt alles 