Lib Funktionen ohne Header nutzen??
-
Ach damt überlesen
Dann verhält sich C++ in einem solchen Fall entweder allgemein nicht wie C, oder nur dieser Compiler nicht (müsste man die C++ Doku lesen).
Aber wenn das "include <cstring>" überall entfernt wird kommt ein Fehler? Sonst wird es interessant ^^
-
Wie gesagt, ich binde in main.cpp den Header Foo.h (in Wirklichkeit heißt er math/Matrix.h) VOR ALLEN anderen Headern ein!
Hier nochmal zur Verdeutlichung wie es exakt im Code aussieht:
Datei Matrix.h:
#ifndef MATRIX_H #define MATRIX_H #include "Types.h" // in Types.h stehen NUR typedefs, sonst nix namespace math { template <class T> class Matrix { private: T* data; unsigned int m, n; public: Matrix(uint rowCount, uint colCount); // usw. }; template <class T> Matrix<T>::Matrix(uint rowCount, uint colCount) : m(rowCount), n(colCount), data(new T[rowCount * colCount]) { char*s1, *s2; printf("hi"); strcmp(s1, s2); }Wie ihr sehen könnt benutze ich im Ctor nach Belieben verschiedene Bibliotheksfunktionen; printf, strcmp, ohne die Header eingebunden zu haben!
meine main.cpp sieht so aus:
#include "math/Matrix.h" #define NOMINMAX #include "DXUT.h" #include "DXUTsettingsDlg.h" // zig weitere Header int main() { ... } void InitApp() { math::Matrix<int> m(3, 4); }Das alles läuft einwandfrei, was ich absolut nicht verstehe. Ich benutze Visual Studio 2005. Versteht jemand, wieso sich das trotz fehlender Header kompilieren lässt??
-
Ich weiss nicht genau wie das bei Templates ist, aber es kann sein, das sie nur auf Syntax ueberprueft werden, erst bei der Instanziierung kommt der ganze Rest. Eine andere Moeglichkeit ist, dass Standardheader in den Projekteinstellungen festgelegt sind und deswegen die Funktionen schon kennt.
-
knivil schrieb:
Ich weiss nicht genau wie das bei Templates ist, aber es kann sein, das sie nur auf Syntax ueberprueft werden, erst bei der Instanziierung kommt der ganze Rest.
Richtig. Zum Zeitpunkt der Instanziierung wird der Code erst wirklich übersetzt, und da sind die ganzen C-Funktionen die du aufrufst schon bekannt.
-
pumuckl schrieb:
knivil schrieb:
Ich weiss nicht genau wie das bei Templates ist, aber es kann sein, das sie nur auf Syntax ueberprueft werden, erst bei der Instanziierung kommt der ganze Rest.
Richtig. Zum Zeitpunkt der Instanziierung wird der Code erst wirklich übersetzt, und da sind die ganzen C-Funktionen die du aufrufst schon bekannt.
Heißt das also das funktioniert, weil zum Zeitpunkt der Instantiierung (also wenn ich in InitApp() ein Objekt der Klasse anlege), alle notwendigen Header in main.cpp indirekt durch andere Header eingebunden wurden?
Aber ich sollte dann dennoch in Header Dateien in denen ich eine Templateklasse definiere alle notwendigen Header einbinden, oder?
-
Verwirrter schrieb:
Heißt das also das funktioniert, weil zum Zeitpunkt der Instantiierung (also wenn ich in InitApp() ein Objekt der Klasse anlege), alle notwendigen Header in main.cpp indirekt durch andere Header eingebunden wurden?
Nicht Objekt-Instanziierung, sondern Klassen-Instanziierung (von einem Template). Das passiert, sobald du das Template das erste Mal mit einem Typen instanziierst, also eine neue Klasse erstellst.
Verwirrter schrieb:
Aber ich sollte dann dennoch in Header Dateien in denen ich eine Templateklasse definiere alle notwendigen Header einbinden, oder?
Ja, du kannst dich ja nicht drauf verlassen, dass der Einbinder alle Abhängigkeiten im Kopf hat. Übrigens: Klassentemplate, nicht Templateklasse.
-
Naja, aber so ganz versteh ich den exakten Vorgang noch immer nicht. Ich mein ich binde in main.cpp meinen Header Matrix.h (sprich die Klassendefinition) ein. Also steht jetzt ganz am Anfang von main.cpp meine Matrixklasse. Wenn ich jetzt keine Matrix-Objekt anlege, wird die Definition einfach ignoriert? Und wenn ich ein Matrix<float> foo anlege, dann instantiiert er eine float Instanz der Klasse. Wo genau wird diese float Instanz der Klasse dann erstellt? Es kann ja offenbar nicht ganz am Anfang von main.cpp sein, denn da sind ja noch keine Header für strcmp, printf etc eingebunden.
-
Du machst einen Denkfehler, der bei Templates oft gemacht wird:
Matrixist keine Klasse, sondern ein Klassentemplate - eine Vorlage für eine Klasse. Also steht am Anfang von main.cpp auch noch keine Klassendefinition. Die Klasse (und deren Definition) wird erst erstellt, sobald du das Template mit einem Typen instanziierst. Zu diesem Zeitpunkt (bei dir in der FunktionInitApp()) sind die C-Funktionen schon deklariert.
-
Nexus schrieb:
Du machst einen Denkfehler, der bei Templates oft gemacht wird:
Matrixist keine Klasse, sondern ein Klassentemplate - eine Vorlage für eine Klasse. Also steht am Anfang von main.cpp auch noch keine Klassendefinition. Die Klasse (und deren Definition) wird erst erstellt, sobald du das Template mit einem Typen instanziierst. Zu diesem Zeitpunkt (bei dir in der FunktionInitApp()) sind die C-Funktionen schon deklariert.Hm ja, ich versuche nur zu verstehen WO genau der Compiler dann eine Instanz des Klassentemplates anlegt. Also ich verstehe ein Template bis jetzt als eine Art Schablone. Und wenn ich ein Objekt mit einem konkreten Typ T anlege, dann sage ich damit dem Compiler: Erstelle jetzt bitte eine konkrete Klasse mit Typ T. Statt meinem Code
template <class T> class Matrix { T* data; ... };erzeugt dann der Compiler diesen Code (wenn ich im Code ein Matrix<float> foo anlege):
class Matrix { float* data; ... };Also ich stelle mir vor, dass der Compiler da wirklich KONKRETEN Code erzeugt und den irgendwo abspeichert. Stimmt das oder liege ich da falsch?
Falls es stimmt frage ich mich eben, WO schreibt der Compiler die konkrete float Klasse hin? Ich habe mir den Kompiliervorgang von main.cpp so vorgestellt:
main.cpp sieht so aus (nachdem der Präprozessor drübergelaufen ist ist):// main.cpp template <class T> Matrix { ... } // Zeile1. Kam aus Matrix.h // alle anderen Deklarationen aus den anderen Headern int main() { ... } void InitApp() { math::Matrix<int> m(3, 4); // Wenn der Compiler auf diese Zeile trifft weiß er: ich muss jetzt eine float Instanz des Matrix-Klassentemplates erstellen. //Ich dachte mir einfach, der Compiler generiert jetzt eine float-Matrixklasse an der Stelle, an der das Klassentemplate steht (sprich Zeile1). //Nur wurde vor Zeile 1 kein Header eingebunden und im Ctor von Matrix benutze ich ja strcmp, printf etc., was dann ja einen Fehler liefern müsste (was es nicht tut) }Offenbar schreibt der Compiler doch nicht die konkrete float Instanz meines Klassentemplates in Zeile1, oder?
-
Verwirrter schrieb:
Also ich stelle mir vor, dass der Compiler da wirklich KONKRETEN Code erzeugt und den irgendwo abspeichert. Stimmt das oder liege ich da falsch?
Klares jein. Der Compiler erzeugt nicht Code, wie du ihn in dschreibst, sondern Zwischencode. Und den erzeugt er genau dann wenn er das erste mal ein Matrix<float> im Sourcecode sieht.