Vorlage, Verknüpfung und Trennung .h und .cc-Dateien
Habe ich schon etwas Lesen in der Gestaltung template-code haben Sie eine Frage über es. Die meisten Lösungen für Probleme in Bezug auf die Gestaltung von code-templates scheinen entweder:
- Setzen Definitionen von Prototypen in der header-Datei
- Verwenden Sie das export-Schlüsselwort wie diese (erfordert eine zusätzliche compiler-option)
- Konkret darlegen, wie die Vorlagen verwendet werden .cc/.cpp Datei.
Beispiel:
//File: foo_impl.cc
//We're working with Class Foo
#include "foo.cc"
template class Foo <int>;
template class Foo <string>;
//etc.
Keiner dieser Methoden scheinen sehr effektiv. Es sei denn, ich bin fehlt etwas, Sie scheinen nicht die Möglichkeit bieten, einem Benutzer einfach importieren die header-Datei und link das template-code (in ein .cc-Datei), ohne dabei zusätzliche Arbeit. Ich Frage mich, ob die Menschen konnten schauen, was ich mache, mit meinem eigenen code und sagen Sie mir, wenn diese gegen irgendeine Art von best practices-Protokoll oder, wenn Sie könnte dazu führen, ein Problem, dass ich einfach nicht sehen. Hier ist, was ich getan habe...
In main.cc:
#include <iostream>
#include "foo.h"
using namespace std;
int main (void) {
Foo <string> f ("hello world");
string s = f.get ();
cout << s << endl;
return 0;
}
In foo.h:
#ifndef FOO_H
#define FOO_H
template <class T>
class Foo {
public:
Foo (T);
T get ();
private:
T data;
};
#endif
#include "foo.cc"
In foo.cc:
#ifndef FOO_CC
#define FOO_CC
#include "foo.h"
template <class T>
Foo :: Foo (T stuff) {
data = stuff;
}
template <class T>
T Foo <T> :: get () {
return data;
}
#endif
Habe ich in der Lage, den code zu kompilieren mit allen Warnungen des gcc 4.1.2. Danke!
- Sind Sie gerade versuchen, um separate Dateien, die wie wir für den normalen c++ - Dateien, um Definitionen und Erklärung in separate Dateien? Oder Sie denken, Sie können sich nicht teilen, Ihren code zur Implementierung auf andere Benutzer, gonna benutzen Sie Ihren code als Bibliothek? U kann erarbeiten, was Sie erreichen wollen?
- Ich möchte nur zur Behandlung von meinem template-code, als wäre es nur ein weiteres .h und .cc-Datei. Ich möchte eine header-Datei, die einfach zu Lesen durch die Aufrufe ohne Füllstoffe es.
- Ich wirklich tun dies auch, mit einem
#ifdef _DEBUG template class Foo <int>; #endif
am Ende, so kann ich erzwingen, dass es kompiliert mit MSVC und sicher sein, dass alles instanziert, ohne Fehler.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Ich persönlich lieber die Erklärung (.h) in eine separate Datei aus der definition (Ihren .cc-Datei). Auch ich möchte vermeiden, einschließlich der .cc-Datei in der .h-Datei. Methoden in einem .h-Datei sollte nur inline-Methoden.
Lassen Sie uns sagen, in Ihrem Beispiel, Sie hatten auch eine header-Datei (bar.h), die einfach deklariert eine Klasse, die eine Foo-Daten Mitglied.
Jedes mal, wenn Sie würden ändern Sie die definition der Klasse "Foo", Sie würde eine erneute Kompilierung wer schließt die bar.h, noch hart Sie konnte es nicht weniger Pflege über die definition von Foo. Allerdings bar.cpp ist wahrscheinlich, wo Sie auch tatsächlich umzusetzen, Sachen und, die Datei FUNKTIONIERT, müssen die Umsetzung Ihrer Vorlage. Dies trivial erscheinen in kleinen Projekten, sondern wird zu einer Quelle von Kopfschmerzen in großen Projekten, die ständig neu kompilieren, Dateien ohne Grund. Ich habe Menschen gesehen, die werfen SSDs und Incredibuild an Zeug, dass könnte behoben werden, indem einfach vorne erklärt und besser header-management.
Persönlich benutze ich .imp.h für die Umsetzung meiner Vorlagen. Einschließlich cc-files oder cpp-Dateien scheint yucky zu mir.
Z.B. ( sorry für die Kompilierung Fehler. 😉 )
Hatte die defintion von " foo " enthalten sein in oder von foo.h, bar.cpp und foobar.cpp müsste neu kompiliert wurde. Da nur bar.cpp befasst sich mit Foo ' s Umsetzung, die Aufteilung der defintion und Deklaration von Foo in zwei Dateien, und nicht foo.h include foo.imp.h am Ende hat mich gerettet zu kompilieren foobar.cpp.
Dies ist etwas, das passiert die ganze Zeit in Projekte und können sehr leicht vermeiden, indem Sie die folgenden die .h/.imp.h Regel, die ich oben erklärt. Der Grund, warum Sie nie sehen diese in Sachen wie STL oder boost ist, weil Sie nicht ändern dieser Dateien. Es spielt keine Rolle, wenn Sie in einer oder zwei Dateien. Aber in Ihren eigenen Projekten, Sie wird ständig ändern die Definitionen Vorlagen, und dies ist, wie Sie reduzieren die Neukompilierung Zeiten.
Wenn Sie bereits vorher wissen, welche Arten sind, die tatsächlich verwendet werden, Ihre Vorlage, als nicht einmal die Mühe, mit der .imp.h-Datei. Setzen Sie alles in einem .cpp und tun dies am Ende
foobar.cpp
erfordertBar
um vollständig definiert sein, die erfordertFoo
vollständig definiert, aber diefoobar.cpp
TU hat nicht gehörenFoo
s Umsetzung, weil es für Sie nicht, rufen Sie eine dieser Funktionen. Meine Kommentare in Seth Carnegie Antwort gab, denn ich konnte nicht denken Sie an ein Beispiel wie dieses. Gut!Beginnen wir mit der grundsätzlichen Ideologie .h und .cc-Dateien. Beim Bau von Bibliotheken, die Idee ist zu teilen nur Ihre header-Dateien und nicht Ihre Implementierung (Mittelwert .cc-Dateien). Dies ist auch die Grundlagen der OOP ist die Kapselung, der Abstraktion usw., zu verstecken die details der Implementierung.
Nun die templates in C++, verstößt gegen dieses Prinzip, bcoz C++ ist eine kompilierte Sprache. Und der compiler erzeugt den code während der Kompilierung. Jetzt einhalten OOP wir am Ende mit fragilen Vorlagen, die nicht zu 100% allgemein in der Natur.
Halten, Erklärung und Definitionen trennen (TEILEN Implementierung)
Wenn Sie nur wollen, um die Dinge sauber und in Ordnung, dann können Sie für Ihre Implementierung die Datei in einem anderen header. Ich denke, es sollte sein, die header-Datei wie das geht mit der grundlegenden übereinkommen, die wir teilen .h-Dateien und wir halten .cc-Dateien, die nicht freigegeben werden (bis Sie die Freigabe der code selbst). Hier ist, wie die Dateien Aussehen.
foo.h
Dies ist einfache Datei mit einschließlich
foo_impl.h
.foo_impl.h
Dieser ist etwas anders als die Norm sind. Hier sind wir nicht die Bewachung der header-Datei Inhalt. Wir werden stattdessen eine Fehlermeldung ausgeben, wenn jemand im Lieferumfang enthalten
foo_impl.h
direkt (was in unserem Fall nicht sinnvoll).Nun, wenn jemand versucht, Sie zu zählen
foo_impl.h
direkt erhalten Fehler wie:VORTEILE:
NACHTEILE:
HINWEIS: Für nicht-sharing-code für templates, ich denke, Sie wissen bereits, dass Sie erklären, alle möglichen Typen, in die die end-Benutzer können es verwenden,.
Inkl .cc-Dateien ist eine schlechte Nachricht und Niederlagen der Zweck der Trennung der Umsetzung von Erklärung.
Vorlagen in Kopfzeilen:
Wenn du wirklich lieber 2 Dateien, dann die zweite .h zu. Name it foo_impl.h oder sowas.
Ist es üblich, Einfluss auf die Trennung von Schnittstelle und Implementierung für Vorlagen von
#include
ing der Umsetzung der Vorlagen, die am Ende der Kopf, aber es gibt drei Probleme mit, wie Sie es tun:#include "foo.cc"
foo.h innen die include-guards, nicht außerhalb.Diese Weise getan, es ist keine zusätzliche Arbeit für den Benutzer zu tun. Alles, was Sie tun, ist
#include
den Kopf, und du bist fertig. Sie nicht kompilieren der Umsetzung.Da Sie auch
foo.cc
imfoo.h
gestalten Sie Ihr Leben einfacher, indem Sie alle den code infoo.h
und loszuwerdenfoo.cc
. Es gibt keinen Vorteil, davon gewonnen zu werden aufteilen des Codes in zwei Stücke.export-Schlüsselwort ist veraltet in c++11. Also, werden Sie am Ende mit veralteten code. Stellen Sie Ihre Definitionen in der header-Datei selbst.