it-swarm.dev

Was tun, wenn ich C ++ - Headerdateien hasse?

Ich war immer verwirrt über Header-Dateien. Sie sind so seltsam: Sie fügen eine .h-Datei hinzu, die keine .cpp enthält, aber .cpp ist auch irgendwie kompiliert.

Kürzlich bin ich einem Teamprojekt beigetreten, und natürlich werden sowohl .h als auch .cpp verwendet.
Ich verstehe, dass dies sehr wichtig ist, aber ich kann nicht damit leben, jede Funktionsdeklaration in jeder unserer Klassen zu kopieren und einzufügen.

Wie gehe ich effizient mit der 2-Dateien-Konvention um?
Gibt es Tools, die Ihnen dabei helfen, oder ändern Sie automatisch eine Datei, die wie im folgenden Beispiel aussieht, in .h und .cpp? (speziell für MS VC++ 2010)

class A
{
...
    Type f(Type a,Type b)
    {
        //implementation here, not in another file!
    }
...
};

Type f(Type a)
{
     //implementation here
}
...
25
Oleh Prypin

Sie könnten Lzz verwenden. Es ist ein Befehlszeilentool, das in einer C++ - Syntax geschriebene Deklarationen verwendet und die Header- und Quelldateien generiert.

3
Mario Becerra

Mehr Refactoring-freundliches C++ schreiben

In C++ müssen Sie überhaupt keine Header verwenden . Sie können das gesamte Objekt in einer Datei genauso definieren wie mit C # oder Java. C-Entwickler behalten normalerweise nur externe Aufrufe in einer Header-Datei. Alle internen Aufrufe würden in der C-Datei definiert. Aus dem gleichen Grund können Sie Ihre C++ .h-Dateien für die Klassen/Schnittstellen (reine virtuelle abstrakte Klassen)/etc. Reservieren. die außerhalb der DLL freigegeben werden sollen. Für interne Klassen/Strukturen/Schnittstellen usw. fügen Sie einfach die CPP-Datei hinzu, die Sie benötigen:

#include<myclass.cpp>

Dies scheint nicht der beliebteste Ansatz zu sein, aber es ist legal C++. Es wäre definitiv eine Möglichkeit für Ihren gesamten internen Code. Auf diese Weise können sich der interne Code und die Klassen viel radikaler ändern und gleichzeitig eine stabilere Schnittstelle für Code außerhalb Ihrer Bibliothek/ausführbaren Datei bereitstellen, mit der Sie interagieren können.

Wenn Sie Ihre gesamte Klasse in einer Datei haben, können Sie leichter tun, was Sie wollen. Es wird nicht das Problem lösen, eine Methode umzubenennen und jeden Ort, an dem diese Methode aufgerufen wird, durchsuchen zu müssen, aber es wird sicherstellen, dass Sie verständlichere Fehlermeldungen haben. Nichts ist schlimmer, als wenn Ihr Header eine Methode in eine Richtung deklariert, aber Sie implementieren sie anders. Anderer Code, der die Header-Datei aufruft, wird ordnungsgemäß kompiliert und Sie erhalten eine Link-Ausnahme, während die Implementierungsdatei diejenige ist, die sich darüber beschwert, dass die Methode nicht definiert wurde. Wenn Sie jede vorhandene Methode definieren (in der eigentlichen Klassendeklaration), wird unabhängig von der darin enthaltenen Datei dieselbe Fehlermeldung angezeigt.

Vielleicht möchten Sie sich auch diese Frage ansehen: Gute Refactoring-Tools für C++

Wie C/C++ Header-/Implementierungsdateien auflöst

Auf der Basis-C-Ebene (und C++ basiert auf dieser Grundlage) deklarieren die Header-Dateien das Versprechen einer Funktion/Struktur/Variablen, das ausreicht Erlauben Sie einem Compiler, die Objektdatei zu erstellen. In ähnlicher Weise deklarieren C++ - Headerdateien das Versprechen von Funktionen, Strukturen, Klassen usw. Diese Definition verwendet der Compiler, um Speicherplatz im Stapel usw. zu reservieren.

Die .c- oder .cpp-Dateien haben die Implementierung. Da der Compiler jede Implementierungsdatei in eine Objektdatei konvertiert, gibt es Hooks für nicht implementierte Konzepte (was im Header deklariert wurde). Der Linker verknüpft die Hooks mit den Implementierungen in anderen Objektdateien und erstellt eine größere Binärdatei, die den gesamten Code enthält (gemeinsam genutzte Bibliothek oder ausführbare Datei).

VS-spezifisch

In Bezug auf die Arbeit mit Visual Studio gibt es einige Assistenten, die die Arbeit etwas vereinfachen. Der neue Klassenassistent erstellt Ihr passendes Paar von Header- und Implementierungsdateien. Es gibt sogar eine Klassenbrowser-Funktion, mit der Sie neue Methoden deklarieren können. Die Definition wird in den Header und der Implementierungsstub in die CPP-Datei eingefügt. Visual Studio hat diese Funktionen seit mehr als einem Jahrzehnt (solange ich sie verwendet habe).

16
Berin Loritsch

Werden Sie ein Java Entwickler.

Wenn Sie wirklich in C++ weiterentwickeln müssen, können Sie versuchen, eine IDE zu verwenden. Oft bieten sie einen Mechanismus, mit dem Sie einer Klasse eine Methode hinzufügen können, und sie platzieren die Deklaration automatisch in der .h-Datei und die Definition in der .cpp-Datei.

13
Paul Butcher

Sie könnten an dem Programm makeheaders von Hwaci interessiert sein (diejenigen, die SQLite und Fossil ausführen).

Schauen Sie sich auch wie Fossil aufgebaut ist an, um eine Idee zu haben.

8
Benoit

Wenn Sie die ersten Zeilen einer neuen Klasse schreiben, liegt dies normalerweise daran, dass Sie sie zu diesem Zeitpunkt nur an einer Stelle benötigen. Zu einem späteren Zeitpunkt wird es möglicherweise an mehreren Orten verwendet, anfangs jedoch normalerweise nicht.

Viele meiner Klassen beginnen oben in der aktuellen CPP-Datei. Wenn es stabil genug ist, um es an mehreren Stellen zu verwenden, füge ich es aus und füge es in eine Kopfzeile ein. Obwohl die Klasse oft so schnell verschwindet, wie es schien.

5
Sjoerd

Die Header (.h) -Datei beschreibt die Schnittstelle zum Code, da dies das nur Bit ist, das andere Code sehen kann.

Die Quelldatei (.cpp) bietet die Implementierung des Codes, über den niemand sonst Bescheid wissen muss.

sie enthalten eine .h-Datei, die keine .cpp enthält ...

Richtig.

Als Benutzer dieses Codes benötigen Sie nur die Header-Datei, damit der Compiler weiß, was in diesem Code verfügbar ist, damit Sie damit arbeiten können. Der C++ - Quellcode wird zu diesem Zeitpunkt in keiner Weise, in keiner Form oder in keiner Form verwendet (oder zumindest sollte nicht sein).

... aber .cpp sind auch irgendwie kompiliert.

Ja das sind, aber komplett separat.

Die CPP-Datei eines von Ihnen verwendeten Moduls/einer Bibliothek wird vom Entwickler dieser Bibliothek in eine Objektdatei (.o/DLL) kompiliert. Diese Objektdatei enthält Einstiegspunkte, die dieselbe "Form" haben wie die in der Header-Datei beschriebenen.

Sie benötigen diese Objektdatei, wenn Sie zu link Ihrer fertigen ausführbaren Datei gelangen. An diesem Punkt kann der Linker den Inhalt der Objektdatei abrufen und in Ihre ausführbare Datei einbetten (dies gilt für statische Verknüpfungen; dynamische Verknüpfungen werden angezeigt) komplizierter)
Grundsätzlich muss der Linker die Punkte zwischen den Einstiegspunkten "verbinden", die Ihr Code erwartet aufrufen kann, basierend auf dem, was er in der Header-Datei gesehen hat und was tatsächlich darin enthalten ist die Bibliothek selbst).

0
Phill W.