Probleme beim compilieren!!!
-
Hallo Leute,
ich bin im Moment mit einem größeren Programm beschäftigt un habe da ein ziemlich nerviges Problem.
Ich habe eine Klasse "AttendantGroup"
/****************************************************************************/ // Include-Gurads #ifndef ATTENDANTGROUP_H #define ATTENDANTGROUP_H /****************************************************************************/ // Headerfiles #include <string> #include <iostream> #include <assert.h> #include "attendantshape.h" using namespace std; /****************************************************************************/ // Preprocessor /****************************************************************************/ // Global Constants: /****************************************************************************/ // Class-Definition class AttendantGroup : public AttendantShape { private: double points_[5]; double totalPoints_; public: AttendantGroup( string lastname = "empty", string firstname = "empty",\ int number = 0); void setPoints(const double points[]); const double* getPoints() const; double getTotalPoints() const; virtual void disqualify(); virtual void undisqualify(); virtual bool isDisqualified(); bool operator<=(const AttendantGroup&); bool operator>=(const AttendantGroup&); bool operator==(const AttendantGroup&); private: void sort(); AttendantGroup(); }; /****************************************************************************/ // Global Functions ostream& operator<<(ostream& o, const AttendantGroup& a); istream& operator>>(istream& i, AttendantGroup& a); bool operator<(const AttendantGroup& l, const AttendantGroup& r); bool operator>(const AttendantGroup& l, const AttendantGroup& r); /****************************************************************************/ // Inline-Functions #ifndef NO_INLINE #include "attendantgroup.inl" #endif /****************************************************************************/ #endif /****************************************************************************die von "AttendantShap erbt"
/****************************************************************************/ // Include-Gurads #ifndef ATTENDANTSHAPE_H #define ATTENDANTSHAPE_H /****************************************************************************/ // Headerfiles #include <string> using namespace std; /****************************************************************************/ // Preprocessor /****************************************************************************/ // Global Constants: /****************************************************************************/ // Class-Definition class AttendantShape{ private: string lastname_; string firstname_; int number_; public: AttendantShape( string lastname = "empty", string firstname = "empty",\ int number = 0); string getLastname() const; string getFirstname() const; int getNumber() const; void setLastname(string&); void setFirstname(string&); void setNumber(int&); virtual void disqualify() = 0; virtual void undisqualify() = 0; virtual bool isDisqualified() = 0; }; /****************************************************************************/ // Global Functions /****************************************************************************/ // Inline-Functions #ifndef NO_INLINE #include "attendantshape.inl" #endif /****************************************************************************/ #endif /****************************************************************************einen Sourcefile um das ganze zu testen
/****************************************************************************/ // Headerfiles #include <iostream> #include <string> #include "attendantgroup.h" using namespace std; /****************************************************************************/ int main(){ AttendantGroup a1(); AttendantGroup a2(); AttendantGroup a3(); AttendantGroup a4(); AttendantGroup a5(); AttendantGroup a6(); return 0; } /**************************************************************************** * Notes: ****************************************************************************/und natürlich die ganzen dazugehörenden cpp- und inl-files.
So wenn ich das ganze jetzt mit
g++ -o test attendantgroup.cpp attendant_test.cppübersetzen will bekomm ich immer einen Linker-Fehler:
attendantgroup.o: In function `operator<<(std::basic_ostream<char, std::char_traits<char> >&, AttendantGroup const&)': attendantgroup.cpp:(.text+0xfc): undefined reference to `AttendantGroup::getPoints() const' attendantgroup.cpp:(.text+0x10a): undefined reference to `AttendantGroup::getTotalPoints() const' attendantgroup.cpp:(.text+0x14c): undefined reference to `AttendantShape::getNumber() const' attendantgroup.cpp:(.text+0x161): undefined reference to `AttendantShape::getFirstname() const' attendantgroup.cpp:(.text+0x176): undefined reference to `AttendantShape::getLastname() const' attendantgroup.o: In function `operator>>(std::basic_istream<char, std::char_traits<char> >&, AttendantGroup&)': attendantgroup.cpp:(.text+0x425): undefined reference to `AttendantShape::setLastname(std::basic_string<char, std::char_traits<char>, std::allocator<char> >&)' attendantgroup.cpp:(.text+0x437): undefined reference to `AttendantShape::setFirstname(std::basic_string<char, std::char_traits<char>, std::allocator<char> >&)' attendantgroup.cpp:(.text+0x449): undefined reference to `AttendantShape::setNumber(int&)' attendantgroup.o: In function `AttendantGroup::AttendantGroup(std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::basic_string<char, std::char_traits<char>, std::allocator<char> >, int)': attendantgroup.cpp:(.text+0x545): undefined reference to `AttendantShape::AttendantShape(std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::basic_string<char, std::char_traits<char>, std::allocator<char> >, int)' attendantgroup.cpp:(.text+0x578): undefined reference to `vtable for AttendantGroup' attendantgroup.o: In function `AttendantGroup::AttendantGroup(std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::basic_string<char, std::char_traits<char>, std::allocator<char> >, int)': attendantgroup.cpp:(.text+0x61d): undefined reference to `AttendantShape::AttendantShape(std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::basic_string<char, std::char_traits<char>, std::allocator<char> >, int)' attendantgroup.cpp:(.text+0x650): undefined reference to `vtable for AttendantGroup' collect2: ld returned 1 exit status make: *** [testgroup] Error 1Hier den cpp-file um den es geht:
/****************************************************************************/ // Headerfiles #include "attendantgroup.h" /****************************************************************************/ // Inline-Funktionen #ifdef NO_INLINE #define inline #include "attendantgroup.inl" #endif /****************************************************************************/ // Function-Implementation /****************************************************************************/ // Function: // Task: // Parameter: // Return: AttendantGroup::AttendantGroup(string lastname, string firstname, int number): \ AttendantShape(lastname, firstname, number),\ totalPoints_(0){ int loop; for(loop = 0; loop < 5; ++loop){ points_[loop] = 0.0; } totalPoints_ = 0; } /****************************************************************************/ // Function: // Task: // Parameter: // Return: void AttendantGroup::setPoints(const double points[]){ int loop; assert((sizeof(points) / sizeof(double)) == 5); if(totalPoints_ != -1){ for(loop = 0; loop < 5; ++loop){ points_[loop] = points[loop]; } } } /****************************************************************************/ // Function: // Task: // Parameter: // Return: void AttendantGroup::sort(){ int loop; int loop2; double tmp; for(loop = 1; loop < 5; ++loop){ for(loop2 = 0; loop2 < loop; ++loop2){ if(points_[loop] < points_[loop2]){ tmp = points_[loop]; points_[loop] = points_[loop2]; points_[loop2] = tmp; } } } } /****************************************************************************/ // Function: // Task: // Parameter: // Return: ostream& operator<<(ostream& o, const AttendantGroup& a){ const double *points = a.getPoints(); double totalPoints = a.getTotalPoints(); o << a.getLastname() << " " << a.getFirstname() \ << " Startnummer: " << a.getNumber() << " " \ << points[0] << " " << points[1] << " " \ << points[2] << " " << points[3] << " " \ << points[4] << " " << totalPoints; return o; } /****************************************************************************/ // Function: // Task: // Parameter: // Return: istream& operator>>(istream& i, AttendantGroup& a){ string tmp; string lastname; string firstname; int number; int totalPoints; double points[5]; i >> lastname >> ws >> firstname >> ws >> tmp >> number >> ws\ >> points[0] >> points[1] >> points[2] >> points[3] >> points[4] >> totalPoints; a.setLastname(lastname); a.setFirstname(firstname); a.setNumber(number); a.setPoints(points); if(totalPoints == -1){ a.disqualify(); } return i; } /****************************************************************************Jetzt sitz ich hier seit 2 Stunden und finde den Fehler nicht. Kann mir einer sagen woran das liegt. Ist wahrscheinlich nur ein dummer Fehler, aber ich seh ihn einfach nicht.
Danke schonmal für die Mühe.
PS: Die .inl-files haben nur den Zweck die .h übersichlicher zu machen und trotzdem das Inlinen von kleinen Methoden zu nutzen.
-
Irgendwas machst du bei deinem ganzen inline-gefummel falsch.
Die Implementierungen zu den entsprechenden Methoden können nicht gefunden werden.Wieso machst du das ganze Gefummel überhaupt?
-
Also ist eigentlich ganz einfach. Wenn du kleine Methoden (so kleine Einzeiler) im Headerfile implementierst, kann der Compiler die "inlinen".
Da ich das aber nicht so gerne habe, wenn Methoden im Headerfile implemtiert werden, deklariere ich die im Headerfile und implementiere die in einem .inl-file, den ich in den Headerfile einbinde.
So ist das übersichtlicher und der inline-Vorteil geht mir nicht verloren.
Klappt sonst immer. Nur in diesem Fall funktioniert da was nicht.
-
Entweder ist NO_INLINE gesetzt oder in den .inl-Files ist etwas falsch.
-
Wenn ich NO_INLINE setze werden die .inl in die .cpp mit eigebunden (für Debug). Das erzeugt übrigens den selben Fehler. Ich schau mir die .inl aber noch mal an.
Und poste sie hier auch mal:
/****************************************************************************/ // Include-Gurads #ifndef ATTENDANTSHAPE_H #define ATTENDANTSHAPE_H /****************************************************************************/ // Function-Implementation /****************************************************************************/ // Function: // Task: // Parameter: // Return: AttendantShape::AttendantShape(string lastname, string firstname, int number) \ :lastname_(lastname), firstname_(firstname), \ number_(number){} /****************************************************************************/ // Function: // Task: // Parameter: // Return: inline AttendantShape::string getLastname() const{ return lastname_; } /****************************************************************************/ // Function: // Task: // Parameter: // Return: inline AttendantShape::string getFirstname() const{ return firstname_; } /****************************************************************************/ // Function: // Task: // Parameter: // Return: inline AttendantShape::int getNumber() const{ return number_; } /****************************************************************************/ // Function: // Task: // Parameter: // Return: inline AttendantShape::void setLastname(string& lastname){ lastname_ = lastname; } /****************************************************************************/ // Function: // Task: // Parameter: // Return: inline AttendantShape::void setFirstname(string& firstname){ firstname_ = firstname; } /****************************************************************************/ // Function: // Task: // Parameter: // Return: inline AttendantShape::void setNumber(int& number){ number_ = number; } /****************************************************************************/ #endif /****************************************************************************/****************************************************************************/ // Include-Gurads #ifndef ATTENDANTGROUP_H #define ATTENDANTGROUP_H /****************************************************************************/ // Function-Implementation /****************************************************************************/ // Function: // Task: // Parameter: // Return: inline double AttendantGroup::getTotalPoints() const{ return totalPoints; } /****************************************************************************/ // Function: // Task: // Parameter: // Return: inline const double* AttendantGroup::getPoints() const{ return points_; } /****************************************************************************/ // Function: // Task: // Parameter: // Return: inline virtual void AttendantGroup::disqualify(){ totalPoints = -1; } /****************************************************************************/ // Function: // Task: // Parameter: // Return: inline virtual void AttendantGroup::undisqualify(){ totalPoints = points_[1] + points_[2] + points_[3]: } /****************************************************************************/ // Function: // Task: // Parameter: // Return: inline virtual bool AttendantGroup::isDisqualified(){ return (totalPoints == -1); } /****************************************************************************/ // Function: // Task: // Parameter: // Return: inline bool AttendantGroup::operator<=(const AttendantGroup& a){ return (totalPoints <= a.totalPoints); } /****************************************************************************/ // Function: // Task: // Parameter: // Return: inline bool AttendantGroup::operator>=(const AttendantGroup& a){ return (totalPoints >= a.totalPoints); } /****************************************************************************/ // Function: // Task: // Parameter: // Return: inline bool AttendantGroup::operator==(const AttendantGroup& a){ return (totalPoints == a.totalPoints); } /****************************************************************************/ // Function: // Task: // Parameter: // Return: inline bool operator<(const AttendantGroup& l, const AttendantGroup& r){ return !(l >= r); } /****************************************************************************/ // Function: // Task: // Parameter: // Return: inline bool operator>(const AttendantGroup& l, const AttendantGroup& r){ return !(l <= r); } /****************************************************************************/ #endif /****************************************************************************
-
Vergesst es ich hab den Fehler gefunden. Die Include-Guards sind falsch.+
Da muss überall _INL statt _H hin. Scheiß copy-paste. Ich wusste es muss ein blöder Fehler sein.
*Gegen den Kopf hau*
-
So nachdme ich alle Syntaxfehler beseitigt habe tuts jetzt alles. Danke.