2012-04-09 13 views
2

Angenommen, Sie erstellen eine Klasse mit mehreren CPP-Dateien (die jeweils die Implementierung einer Memberfunktion enthalten) und haben die Deklaration der Klasse in einer .h-Datei. Außerdem enthält jede CPP-Datei die .h-Datei über die Include-Direktive.Separate Kompilierung in C++

Ich wurde gesagt, dass, wenn Sie die Implementierung von einer der Member-Funktionen (.cpp-Dateien) ändern, müssen Sie jede CPP-Datei neu kompilieren, um das Programm auszuführen. Das heißt, wenn ich 5 Mitgliedsfunktionen hätte (jede in einer CPP-Datei implementiert) und ich die Implementierung von 1 der CPP-Dateien geändert hätte, müsste ich die 1. CPP-Datei, die ich geändert habe UND die 4 anderen CPP-Dateien kompilieren hat sich nicht geändert, um mein Programm korrekt auszuführen.

Meine Frage, wenn die vorherige Aussage wahr ist, ist, warum ist die Aussage wahr? Jeder Einblick in dieses Konzept wäre hilfreich.

+0

Siehe [ähnliche Frage] (http://stackoverflow.com/questions/9188101/recompile-after-base-class-change/9188135) in Bezug auf Basisklassen. –

Antwort

4

Es ist falsch. Wenn an einer bestimmten Implementierungsdatei keine Änderungen vorgenommen werden, keine Änderungen an den darin enthaltenen Headerdateien vorgenommen werden und keine Änderungen an der Umgebung oder den Compileroptionen vorgenommen werden, ist eine erneute Kompilierung nicht erforderlich. Alles, was sich auf die Kompilierung dieser Datei auswirkt, hat sich nicht geändert.

In der Tat können Sie jede der Dateien kompilieren, ohne überhaupt irgendwelche der anderen zu haben. Dann können Sie alle kompilierten Dateien miteinander verbinden, ohne dass sich alle Implementierungsdateien jemals an derselben Stelle befinden.

+0

Header-Dateien sind auch C++ - Dateien ... mit dem Begriff "Implementierung" -Datei oder sogar eine Liste der allgemeinen Erweiterungen ala .cc/.cpp, ist weniger verwirrend .... –

+1

@TonyDelroy Danke. Erledigt. –

3

Die Aussage ist falsch. In der Tat besteht der ganze Grund make (und ähnlich), weil es falsch ist - sie minimieren den Aufwand für die Neuerstellung einer Anwendung, indem sie verfolgen, welche Quelldateien sich geändert haben, und nur die von der Quelle abhängigen Objektdateien neu erstellt Dateien, die sich geändert haben. Objektdateien, die aktuell sind, werden einfach in Ruhe gelassen.

Sobald alle Objektdateien auf dem neuesten Stand sind, werden sie miteinander verknüpft, um die endgültige ausführbare Datei zu erzeugen (und dies wiederum wird normalerweise nur ausgeführt, wenn mindestens eine Objektdatei neuer als die aktuelle ausführbare Datei ist).

Natürlich ist es auch möglich, make für Jobs zu verwenden, die nicht mit dem Kompilieren und Verknüpfen zusammenhängen, aber das ist mit ziemlicher Sicherheit der Gebrauch, den sie am häufigsten verwenden, und (zumindest größtenteils) der Grund, warum sie erfunden wurden (Die einzige offensichtliche Änderung ist, dass sie ursprünglich hauptsächlich für C-Quellcode und nicht für C++ verwendet wurden, aber in dieser Hinsicht sind die beiden fast nicht zu unterscheiden.

Der einzige offensichtliche Unterschied zwischen den beiden ist, dass, wenn/wenn Sie Vorlagen verwenden, Sie in der Regel eine Menge Code in die Header setzen. In diesem Fall erzwingt das Ändern eines Headers das erneute Kompilieren des gesamten Codes, der diesen Header enthält, was oft sehr viel ist. Mit C-Code und/oder nicht-Vorlage C++ - Code, Sie den Großteil des Codes in eine Quelldatei, so dass Sie nur andere Dateien neu kompilieren müssen, wenn Sie die Schnittstelle auf den Code ändern (die in der Regel die Kopfzeile ändern würde)), aber nur diese Datei muss erneut kompiliert werden, wenn Sie Ihre Änderungen auf die Implementierung beschränken, ohne die Schnittstelle zu ändern.

+0

+1 für eine gute Antwort, obwohl natürlich private und geschützte Mitglieder, Inline-Funktionen usw. sind andere Beispiele für "Implementierung" oft in den Headern gefunden. PMCs Antwort listet einige Links zu diesen .... –

1

Wie andere gesagt haben, ist die Aussage falsch. Es gibt jedoch interessante Komplikationen in Bezug auf geänderte Quelldateien, Quellenabhängigkeiten und Neukompilierung.Die hilfreichen Diskussionen hierzu sind, wenig überraschend, in einer Reihe von Guru der Woche Beiträge von Herb Sutter, in welcher sie Abhängigkeits Isolation und das Pimpl Idiom diskutiert:

Compilation Firewalls

The Fast Pimpl Idiom

The Joy of Pimpls

Dieses Zeug erscheint es fast jedem beim ersten Mal esoterisch, aber das Pimpl-Idiom entpuppt sich als erstaunlich in der Praxis nützlich.