Es gibt Kompromisse.
Wenn Sie die Implementierung einer Funktion ändern, muss die gesamte Übersetzungseinheit in eine neue Objektdatei neu kompiliert werden.
Wenn Sie nur eine einzige Funktion pro Übersetzungseinheit schreiben, minimieren Sie die Länge der Kompilierungszeit, die durch unnötige Neuerstellungen verursacht wird.
Auf der anderen Seite, indem Sie eine einzelne Funktion pro Übersetzungseinheit schreiben, maximieren Sie die Länge der Kompilierungszeit von Grund auf, weil es langsamer ist, viele kleine TUs als einige wenige TUs zu kompilieren.
Die optimale Lösung ist die persönliche Präferenz, aber normalerweise irgendwo zwischen "single function per TU" und "one massiver TU für das gesamte Programm" (anstatt genau einer davon). Für Elementfunktionen ist eine TU pro Klasse eine beliebte Heuristik, aber nicht immer die beste Wahl.
Eine weitere Überlegung ist die Optimierung. Aufrufe von Nicht-Inline-Funktionen können inline erweitert werden, jedoch nur innerhalb derselben Übersetzungseinheit. Daher ist es für den Compiler einfacher, eine einzelne massive TU zu optimieren.
Natürlich können Sie die Funktionen inline in der Header-Datei definieren, aber das führt zu einem Problem beim erneuten Erstellen, denn wenn eine der Inline-Funktionen geändert wird, müssen alle, die den Header enthalten, neu erstellt werden. Dies ist ein schlechteres Problem, als einfach größere TUs zu haben, aber nicht so schlecht wie eine massive TU.
Also, die Definition von verwandten nicht-inline-Funktionen innerhalb der gleichen TU ermöglicht dem Compiler, über die Optimierung innerhalb dieser TU zu entscheiden, während eine Rebuild-Kaskade verhindert wird. Dies ist vorteilhaft, wenn diese verwandten Funktionen von einer Inline-Erweiterung profitieren und sich gegenseitig viel aufrufen würden.
Dieser Vorteil wird durch ganze Programmoptimierung gemildert.
Dritte Überlegung ist Organisation. Es ist wahrscheinlich, dass ein Programmierer, der die Elementfunktion einer Klasse betrachtet, auch an anderen Elementfunktionen dieser Klasse interessiert ist. Wenn sie in derselben Quelldatei gespeichert sind, können sie weniger Zeit für die Suche in der richtigen Datei aufwenden.
Der organisatorische Vorteil, alle Klassenfunktionen in einer gemeinsamen Quelldatei zu gruppieren, wird durch moderne IDEs gemildert, die einen schnellen Sprung von der Quelldatei zum Header und von dort zur anderen Funktion ermöglichen.
Vierte Überlegung ist die Leistung des Editors. Das Analysieren einer Datei mit Zehntausenden von Zeilen oder mehr kann langsam sein und je nach Parsing-Technik viel Speicher belegen. Eine massive TU verursacht das nicht notwendigerweise, da Sie separate Dateien verwenden können, die nur zusammen enthalten sind.
Auf der anderen Seite kann eine große Anzahl von Dateien für einige Dateibrowser (wahrscheinlich nicht viel heutzutage) und auch für Versionskontrollsysteme problematisch sein.
Endlich meine Meinung: Ich denke, dass eine Quelldatei pro Klasse eine anständige Heuristik ist. Aber es sollte nicht religiös befolgt werden, wenn es nicht angemessen ist.
Jede Klasse ist in einem Header deklariert, der mit der Klasse selbst zu tun hat. Dann gibt es in der zugehörigen Quelldatei Implementierungen von Methoden, die mit dem Objekt selbst zu tun haben (wie Sie gesagt haben, getters, setter, ctors/dtors ...). Dann werden andere Methoden (die in fast der gesamten Klassenhierarchie überschrieben werden) in einem vollständig getrennten Teil des Projekts implementiert. – NoImaginationGuy
Wenn Sie Archiv aus Objektdateien erstellen, wird Linker nur die Objektdateien auswählen, die benötigt werden, aber beachten Sie, dass, wenn es sich entscheidet, eine Objektdatei auszuwählen, die ganze Objektdatei enthalten ist, nicht nur ein Teil, der benötigt wird Ich denke, es ist besser, Funktionalität in mehreren Objektdateien zu trennen und dann Archiv von ihnen zu erstellen. – PcAF