Ich kompiliere eine statische C ++ - Bibliothek, und da alle Klassen Vorlagen enthalten, befinden sich die Klassendefinitionen und Implementierungen alle in Header-Dateien. Als Ergebnis scheint es (unter Visual Studio 2005), dass ich eine .cpp-Datei erstellen muss, die alle anderen Header-Dateien enthält, damit sie korrekt in die Bibliothek kompiliert werden kann.
Warum ist das?
Der Compiler kompiliert keine Header-Dateien, da diese in Quelldateien eingebunden werden sollen. Bevor eine Kompilierung stattfindet, nimmt der Präprozessor den gesamten Code aus allen enthaltenen Header-Dateien und speichert diesen Code in den Quelldateien, in denen sie enthalten sind, genau an dem Ort, an dem sie enthalten sind. Wenn der Compiler auch die Header-Dateien kompilieren würde, hätten Sie zum Beispiel mehrere Definitionen für viele Dinge.
Beispiel, dies sieht der Präprozessor:
%Vor%-
%Vor%Und das sieht der Compiler:
%Vor%Auch wenn Sie eine CPP-Datei erstellen, erhalten Sie immer noch nichts. Sie müssen Vorlagen instanziieren, um sie in die Bibliothek zu legen.
Sehen Sie hier nach Ссылка darüber, wie Vorlagen mit konkreten Typen instanziiert werden.
In Templates sind Templates nur eine Meta-Definition einer tatsächlichen Klasse. Wenn Sie eine Vorlagenklasse kompilieren, generiert der Compiler tatsächlich den Code für die aktuelle Klasse für den bestimmten Typ der übergebenen Daten (die Vorlage ist nur ein "Muster" zum Kopieren).
z.B. Wenn Sie den folgenden Code haben
%Vor%Was der Compiler tatsächlich sieht, ist
%Vor%Wie Sie wahrscheinlich sehen können, weiß der Compiler nicht wirklich, welchen Code generiert werden soll, bis Sie tatsächlich eine Instanz Ihrer Vorlage deklarieren. Dies bedeutet, dass die Vorlage nicht in eine Bibliothek kompiliert werden kann, weil sie nicht weiß, was die Vorlage tatsächlich sein wird. Die gute Nachricht dabei ist, dass Sie wirklich keine Bibliothek kompilieren oder einbeziehen müssen, wenn Sie nur die Headerdateien verteilen, die die Vorlagendefinition enthalten.
Als Nebenbemerkung teilt der '# include' Pre-Compiler-Befehl dem Pre-Compiler eigentlich nur mit, den '# include' mit allem aus dieser Datei zu ersetzen.
Wenn sich Ihr gesamter Code in .h-Dateien befindet, müssen Sie keine statische Bibliothek kompilieren, um den Code zu verwenden.
Der gesamte Code steht der Bibliothek zum Zeitpunkt der Kompilierung zur Verfügung, sodass zum Zeitpunkt der Verknüpfung nichts benötigt wird.
Sie versuchen, etwas unnötiges zu schaffen. Die meisten C-Bibliotheken (und alle C ++ - Bibliotheken) werden als zwei Teile verteilt:
foo.h
) foo.lib
) Für C ++ - Vorlagencode muss Ihre gesamte Bibliothek von Ihren Endbenutzern kompiliert werden, da Vorlagen so funktionieren. Es gibt keinen Grund, eine vorkompilierte Bibliothek bereitzustellen. In diesem Fall können Sie sich Ihre Bibliotheksverteilung so vorstellen:
foo.h
) foo-inl.h
) Wie Niel bereits gesagt hat, ist es nützlich, Implementierungen nur für Ihre eigenen Testzwecke zu haben, und es lohnt sich, diese mit der Library selbst zu verteilen. Sie sollten also eine separate Suite von Komponententests haben, die Ihren Code auswerten; aber diese Tests sollten nicht Teil der Bibliothek selbst sein.
Wenn Ihre Bibliothek vollständig in Headerdateien implementiert ist, müssen Sie keine Binärdatei erstellen, um sie zu verwenden. Das gesagt. Ich erstelle normalerweise eine .cpp-Datei während meiner anfänglichen Entwicklungsphase der Nur-Header-Bibliothek. Warum? Compiler versuchen nicht, Ihre Vorlage zu kompilieren oder gar zu parsen, bis sie tatsächlich verwendet wird. Wenn Sie eine CPP-Datei haben und dort Dummy-Code zum Instanziieren der Templates haben, kann ich Syntaxfehler früher während der Entwicklung finden. So kann ich einen Template-Code hinzufügen, den Kompiliervorgang starten, den Syntaxfehler korrigieren, mehr Code hinzufügen, ... kompilieren. Wenn Sie versuchen, einige dumme Syntaxfehler nach dem Hinzufügen von Hunderten von Codezeilen zu finden, werden Sie wissen, was ich meine. Sobald meine Bibliothek für den Komponententest bereit ist, entferne ich die .cpp-Datei und verlasse mich auf Unit-Tests, um meine Entwicklung voranzutreiben.
Wenn Sie Ihren Code nur mit VC ++ kompilieren, müssen Sie sich darüber im Klaren sein, dass VC ++ nicht versucht, alle Vorlagenelementfunktionen zu kompilieren, bis sie tatsächlich verwendet werden. Zum Beispiel:
%Vor%Das f () wird gut mit VC ++ 2003 kompilieren, g ++ wird den Syntaxfehler abfangen. Ich denke, VC8 und VC9 haben auch das gleiche Problem.
Was andere gesagt haben, ist wahr, wenn Vorlagen nicht in die Bibliothek kompiliert werden. Es lohnt sich jedoch immer noch, sie vom Compiler zu sehen (indem man sie in eine .cpp-Datei einfügt), damit sie zumindest auf Syntax geprüft werden.
Sie müssen keine .lib-Datei generieren, wenn alle Klassen Vorlagen sind, einen Boost oder einen anderen Hinweis ziehen. Sie haben keine .lib, die sie verteilen [1].
Vorlagen werden bei ihrer Verwendung kompiliert.
[1] Genau genommen verteilen sie Bibliotheken für die fortgeschritteneren Funktionen wie reguläre Ausdrücke, Iostream usw., aber Hilfs-Bibliotheken werden von anderen Vorlagen verwendet, die Vorlagen selbst sind nicht in Bibliotheksform verteilt.
Tags und Links c++ code-organization