Wie kann eine C ++ - Headerdatei eine Implementierung enthalten?
Ok, kein C/C++ Experte mit allen Mitteln, aber ich dachte den Punkt einer header-Datei war zu erklären, dass die Funktionen, dann die C/CPP-Datei zu bestimmen, die Umsetzung.
Aber die Beurteilung von einigen C++ - code heute Abend, ich fand das eine Klasse header-Datei...
public:
UInt32 GetNumberChannels() const { return _numberChannels; } //<-- Huh??
private:
UInt32 _numberChannels;
Warum also gibt es eine Umsetzung in einem header? Hat es zu tun mit der const
keyword? Nicht, dass inline-Methode einer Klasse? Was genau ist der Vorteil/Zeitpunkt, es zu tun auf diese Weise gegen die Definition, die Implementierung in die CPP-Datei?
Kommentar zu dem Problem
Die Funktion inline.
Dies ist nur eine der Möglichkeiten, um die Deklaration einer inline-Funktion in C++.
RE die
const
qualifier; es bedeutet nur, dass die Methode nicht verändern den Zustand des Objekts. @Alex: Sie sind falsch, muss der compiler die inline-Funktion. Der compiler/linker zu tun haben mit dem mehrere Definitionen (inline-Funktionen werden nicht unter die one-definition-rule).
@Alex Nein der compiler nicht inlien. Es kann inline in einigen übersetzungs-untis aber nicht tun müssen, so in allen TU. Ja, es gibt mehrere Definitionen, da aber die Funktion ist (implizit) inline deklariert, kann der compiler markiert das symbol, wenn es nicht inline, und der linker weiß, es zieht nur einer der exportierten Symbole. Es ist das gleiche für template-Instanziierungen.
InformationsquelleAutor der Frage MarqueIV | 2013-01-25
Du musst angemeldet sein, um einen Kommentar abzugeben.
Den wahren Zweck einer header-Datei ist die gemeinsame Nutzung von code zwischen mehreren source-Dateien. Es ist Häufig verwendet, um separate Deklarationen von Implementierungen, die für eine bessere code-management, aber das ist keine Anforderung. Ist es möglich, code zu schreiben, der sich nicht auf header-Dateien, und es ist möglich, code zu schreiben, der aus nur header-Dateien (STL und Boost Bibliotheken sind gute Beispiele dafür). Denken Sie daran, wenn die Präprozessor trifft auf eine
#include
Aussage, es ersetzt die Anweisung mit dem Inhalt der Datei verwiesen wird, dann ist die compiler sieht nur die fertig formatierten code.So, zum Beispiel, wenn Sie die folgenden Dateien:
Foo.h:
Foo.cpp:
Bar.cpp:
Den Präprozessor analysiert Foo.cpp und Bar.cpp separat und erzeugt den folgenden code, der die compiler dann analysiert:
Foo.cpp:
Bar.cpp:
Bar.cpp kompiliert in Bar.obj und enthält eine Referenz zu nennen, in
Foo::GetNumberChannels()
. Foo.cpp kompiliert wird in Foo.obj und enthält die eigentliche Implementierung derFoo::GetNumberChannels()
. Nach dem kompilieren, die linker dann passt das .obj-Dateien und links, die Sie zusammen zur fertigen ausführbaren Datei.Durch, einschließlich die Implementierung der Methode innerhalb der Methode Erklärung, es wird implizit deklariert als inline (es gibt eine tatsächliche
inline
Schlüsselwort, das explizit als gut). Darauf hinweist, dass sollte der compiler die inline-Funktion ist nur ein Hinweis, die keine Garantie, dass die Funktion tatsächlich inlined. Aber wenn es funktioniert, dann überall dort, wo die inline-Funktion aufgerufen wird, der Inhalt der Funktion kopiert werden, die direkt in den Ruf Website, anstatt der Erzeugung einerCALL
Anweisung zum Sprung in die Funktion und springt zurück an den Aufrufer, die beim verlassen. Der compiler kann dann die umliegenden code zu berücksichtigen und optimieren Sie den kopierten code weiter, wenn möglich.Nicht. Die
const
keyword deutet lediglich an den compiler, dass die Methode nicht verändern den Zustand des Objekts aufgerufen wird, zur Laufzeit.Wenn effektiv genutzt, kann der compiler in der Regel schneller und besser optimierten Maschinen-code.
InformationsquelleAutor der Antwort Remy Lebeau
Es ist vollkommen gültig, um eine Implementierung einer Funktion in einer header-Datei. Das einzige Problem mit diesem ist, brechen die one-definition-rule. Das heißt, wenn Sie den Kopf aus mehreren anderen Dateien, erhalten Sie einen compiler-Fehler.
Allerdings gibt es eine Ausnahme. Wenn Sie deklarieren eine Funktion inline ist es befreit von der one-definition-rule. Das ist das, was hier geschieht, da die Funktionen die in einer Klasse definiert definition sind implizit inline.
Inline selbst ist ein Hinweis an den compiler, dass eine Funktion kann einen guten Kandidaten für inlining. Das ist, baut jeder Aufruf von ihm, in der definition der Funktion, anstatt einen einfachen Funktionsaufruf. Dies ist eine Optimierung, die-trades die Größe der erzeugten Datei für schnelleren code. In modernen Compilern, die Bereitstellung dieser inlining Hinweis für eine Funktion wird meist ignoriert, mit Ausnahme der Auswirkungen hat es auf die one-definition-rule. Auch ein compiler ist immer kostenlos zu inline-jede Funktion, die Sie für richtig hält, auch wenn es nicht deklariert wurde
inline
(explizit oder implizit).In deinem Beispiel, die Verwendung von
const
nach der argument-Liste signalisiert, dass Sie die member-Funktion ändert nicht das Objekt, auf dem es aufgerufen wird. In der Praxis bedeutet dies, dass das Objekt verweistthis
, und durch die Erweiterung alle class-Mitglieder, werden alsconst
. Das heißt, zu versuchen, Sie zu ändern, generiert einen Kompilierungsfehler.InformationsquelleAutor der Antwort Agentlien
Es ist implizit erklärt
inline
aufgrund der Tatsache, eine member-Funktion definiert innerhalb der Klassendeklaration. Dies bedeutet nicht, dass der compiler hat inline, aber es bedeutet, dass Sie nicht brechen die one definition rule. Es ist völlig unabhängig vonconst
*. Es hat auch nichts mit der Länge und der Komplexität der Funktion.Wenn es eine nicht-member-Funktion, dann hätten Sie explizit deklarieren es als
inline
:* Siehe hier für mehr auf
const
am Ende einer member-Funktion.InformationsquelleAutor der Antwort juanchopanza
Sogar in plain C ist, ist es möglich, code in eine header-Datei. Wenn Sie es tun, müssen Sie in der Regel zu erklären, es
static
oder sonst mehrere .c-Dateien mit dem gleichen header zu einem "multiply-defined function" - Fehler.Den Präprozessor textlich beinhaltet die eine include-Datei, so dass der code in eine include-Datei wird zu einem Teil der source-Datei (zumindest aus der compiler-Sicht).
Den Designern von C++ wollte Sie aktivieren Objekt-orientierte Programmierung mit guten Daten versteckt, so dass Sie erwarten, um zu sehen, viele getter-und setter-Funktionen. Sie wollte nicht, dass eine unzumutbare Einbußen bei der Leistung. So gestalteten Sie C++, so dass der Getter und setter konnte nicht nur erklärt werden, in der Kopfzeile, sondern tatsächlich umgesetzt, so würden Sie inline. Die Funktion, die Sie gezeigt haben, ist ein getter ist, und wenn C++ - code kompiliert wird, wird es keine Funktion aufrufen, code herauszuholen, der Wert wird nur kompiliert werden, statt.
Es möglich ist, um eine computer-Sprache, die nicht die header-Datei/Quelldatei-Unterscheidung, sondern eben die tatsächliche "Modulen", die der compiler versteht. (C++ trifft das nicht tun, Sie einfach und baut auf dem erfolgreichen Modell der C-Quellcode-Dateien und textlich enthalten header-Dateien.) Wenn Quell-Dateien handelt es sich um Module, es wäre möglich, einen compiler zu ziehen-code aus der Modul und dann inline-code. Aber die Art, wie C++ hast, ist es einfacher zu implementieren.
InformationsquelleAutor der Antwort steveha
Soweit ich weiß, gibt es zwei Arten von Methoden, die sicher sein kann, umgesetzt innerhalb der header-Datei.
Ich glaube, dein Beispiel passt der erste Fall.
InformationsquelleAutor der Antwort Spook
Halten die Umsetzung in der Klasse header-Datei funktioniert, da bin ich mir sicher, dass Sie wissen, wenn Sie kompiliert deinen code. Die
const
Schlüsselwort sorgt Sie sich nicht ändern, die keine Mitglieder sind, hält sich die Instanz unveränderlich für die Dauer des Methodenaufrufs.InformationsquelleAutor der Antwort Jonas Byström