inline wird nicht kompiliert?
-
Hiho
hab folgenden Klassenheader:
class Snowflake { public: Snowflake(Position Pos, Vector Move); Snowflake(int PosX, int PosY, float MoveX, float MoveY); void move(); void changeMovement(float NewX= 0, float NewY= 0); // getter int PosX() const {return mPos.x;} int PosY() const {return mPos.y;} // setter (returning changeable Reference) float& MoveX() {return mMovement.x;} float& MoveY() {return mMovement.y;} private: Position mPos; Vector mMovement; };
und dazu die folgende Implementierung:
#include "Snowflake.h" Snowflake::Snowflake(Position Pos, Vector Move) /******************************************************************** * ctor ********************************************************************/ : mPos(Pos), mMovement(Move) { } Snowflake::Snowflake(int PosX = 0, int PosY = 0, float MoveX = 0.0, float MoveY = 0.0) /******************************************************************** * ctor, with default-arguments ********************************************************************/ : mPos(PosX, PosY), mMovement(MoveX, MoveY) { std::srand( std::time(0) ); } inline void Snowflake::move() /******************************************************************** * moves the flake by a step defined in his mDirection-Vector ********************************************************************/ { mPos.x += mMovement.x; mPos.y += mMovement.y; } inline void Snowflake::changeMovement(float NewX, float NewY) /******************************************************************** * changes the movement of the snowflake * if both X- and Y-Movement stay the same ( = method is called * without arguments), the movement will changes randomly ********************************************************************/ { if (NewX == 0 && NewY == 0) { // change randomly NewX = (std::rand() % 100) / 100.0; NewY = (std::rand() % 100) / 100.0; } mMovement.x = NewX; mMovement.y = NewY; }
beim Compilieren mault aber immer der Linker:
[Linker Fehler] Unresolved external 'Snowflake::changeMovement(float, float)' referenced from D:\MY_PROJECTS\BLUESNOWSIM\MAINFORM_SRC.OBJ [Linker Fehler] Unresolved external 'Snowflake::move()' referenced from D:\MY_PROJECTS\BLUESNOWSIM\MAINFORM_SRC.OBJ
wobei mainform_src.cpp die Datei ist, die die Funktionen move() und changeMovement() aufruft.... warum kompiliert das nicht?
(sry wenn ich soviel Code geposted hab, aber ich hab keinen Plan wo genau der Fehler liegt)
P. S. warum konnte ich in Snowflake::changeMovement() die Default-Parameterwerte nicht erst in der Implementierung angeben? (dann meldete der Kompiler, dass zuwenig Parameter beim Aufruf angegeben wurden)
-
inlinefunktionen müssen im gleichen file stehen, wie die klasse, sie können nicht außerhalb des files gefunden werden.
du musst die implementierungen unter die klasse schreiben.
wozu eigentlich an dieser stelle inline?
-
elise schrieb:
wozu eigentlich an dieser stelle inline?
genau dass wäre auch meine Frage gewesen
-
elise schrieb:
inlinefunktionen müssen im gleichen file stehen, wie die klasse, sie können nicht außerhalb des files gefunden werden.
du musst die implementierungen unter die klasse schreiben.
wozu eigentlich an dieser stelle inline?
gibts da einen guten Grund fuer?
(ich mein, grundlos wird das wohl net so sein, oder? schon mal sry fuer die dumme Frage *g* )
Warum die Funktion inline ist? sie wird nur von einer einzigen anderen (ziemlich zeitintensiven) Funktion aufgerufen, deshalb glaub ich mit dem inline etwas mehr Speed rauszuholen
und was ist mit den Default-Argumenten? mit dem GCC konnt ich die auch erst in der Implementierung festlegen
-
Blue-Tiger schrieb:
Warum die Funktion inline ist? sie wird nur von einer einzigen anderen (ziemlich zeitintensiven) Funktion aufgerufen, deshalb glaub ich mit dem inline etwas mehr Speed rauszuholen
Soweit ich informiert bin, kann man zwar dem Compiler sagen, daß man diese Methode gerne inline haben möchte, der Compiler (zumindest der BCB) entscheidet aber alleine darüber, ob er ihn inline macht oder nicht (das macht er ggf. auch bei Methoden, die nicht als inline gekennzeichnet sind). Es gibt bei den Compileooptionen ja auch die Möglichkeit, auf Größe oder Geschwindigkeit zu optimieren. Da hat inline sicher auch einen Einfluß darauf.
Eine Inline-Methode darf deshalb aber nur sehr klein sein und wird nur bei, 1 bis 3 Codezeilen verwendet, weil Inline ja wie ein Makro wirkt. Es kann also sein, daß inline vom Compiler bei dieser Methode ignoriert wird. Notfalls empfehle ich wirklich den Einsatz eines Makros, wobei ein Methodenaufruf soooo teuer auch nicht ist...
Blue-Tiger schrieb:
und was ist mit den Default-Argumenten? mit dem GCC konnt ich die auch erst in der Implementierung festlegen
Beim BCB muß man Defaults in der Deklaration festlegen. Ist eigentlich auch übersichtlicher, find ich und wenn ich eine Klasse importiere, includiere ich ja die include-Datei und dort steht die Deklaration. Die Definition läuft in einem anderen Codemodul, auf das mein Codemodul gar keinen Zugriff hat.
-
Hallo,
die Definition einer als inline-deklarierter Funktion muss überall dort sichtbar sein, wo diese Funktion aufgerufen wird. Der Grund dafür liegt im Übersetzungsmodell von C++. Hier werden immer einzelne Übersetzungseinheiten verarbeitet. Nicht das gesamte Programm auf einmal.
Da ein Aufruf einer inline-Funktion ja nun durch die Implementation der Funktion ersetzt wird (falls der Compiler sich dazu entschließt sie inline zu machen), muss die Implementation natürlich auch zur Verfügung stehen. Deshalb die oben genannte Regel.Hast du also z.B. eine inline-Funktion foo in der Datei a.cpp definiert, und ruft b.cpp diese Funktion auf, dann müsste der Compiler den Inhalt von a.cpp kennen um b.cpp übersetzen zu können, da er ja schließlich die Definition von foo braucht.
Eine Inline-Methode darf deshalb aber nur sehr klein sein und wird nur bei, 1 bis 3 Codezeilen verwendet, weil Inline ja wie ein Makro wirkt.
Zu sagen inline wirke wie ein Makro und dann im nächsten Atemzug die Benutzung von Makros vorzuschlagen, verfehlt genau die entscheidenen Unterschiede zwischen inline-Funktionen und Makro-*Pseudo*-Funktionen.
inline wirkt in den wichtigen Punkten eben gerade nicht wie ein Makro.Notfalls empfehle ich wirklich den Einsatz eines Makros, wobei ein Methodenaufruf soooo teuer auch nicht ist...
Makros als Pseudo-Funktionen sind in C++ ein unnötiges Verbrechen. Warum Pseudo, wenn es auch richtig geht?
-
HumeSikkins schrieb:
Zu sagen inline wirke wie ein Makro und dann im nächsten Atemzug die Benutzung von Makros vorzuschlagen, verfehlt genau die entscheidenen Unterschiede zwischen inline-Funktionen und Makro-*Pseudo*-Funktionen.
inline wirkt in den wichtigen Punkten eben gerade nicht wie ein Makro.Mir ist klar, daß ich in einem Makro auch einen Block definieren kann, um also die Dinge der Makrofunktion zu verbergen und ich habe in einem Makro keinen Zugriff auf die privaten/protected Elemente der Klasse. Aber welche wichtigen Punkte siehst Du da noch?
-
Aber welche wichtigen Punkte siehst Du da noch?
Auf die Schnelle?
a) Fehleranfallig: Gefahr unzureichender Klammerung
b) Fehleranfällig: Mehrfachauswertung möglich bei Seiteneffekten im Aufruf
c) Keine Ahnung von C++ Scope-Regelen. Es wird alles zertrampelt, was dem Makro in den weg kommt. Dazu solche Sachen wie:int count; #define exec(func) (func(), ++count) // ... void func() { int count = 0; while(count++ < 10) { exec(anotherFunc); // OOOPS! Ändert *lokales* count } }
d) Keine Ahnung von C++ Typregeln
e) Kein lvalueInline-Funktionen haben keins dieser Probleme, da sie eben zu C++ gehören und nicht nur auf lexikalischer Ebene agieren.
-
Danke für die Info! Aber eigentlich war mir das vorher schon klar. Wenn ich Makros anwende (bzw. den gleichen Codeteil immer wieder an den passenden Stellen dupliziere), dann muß ich ja aber auch wissen, was ich mache (wie mit so vielem). Insofern hast Du gewiß nicht Unrecht, aber meine Makrolösung kann bei zeitkritischen Sachen und durchdachter Implementierung aber auch so zuverlässig wie eine Methode funktionieren (bis auf das Problem mit dem Zugriff auf private/protected Elemente einer Klasse logischerweise).