Ich bin ein JAVA-Entwickler, der versucht, C ++ zu lernen, aber ich weiß nicht wirklich, was die beste Vorgehensweise für Standardfunktionsdeklarationen ist.
In der Klasse:
class Clazz
{
public:
void Fun1()
{
//do something
}
}
Oder draußen:
class Clazz
{
public:
void Fun1();
}
Clazz::Fun1(){
// Do something
}
Ich habe das Gefühl, dass der zweite weniger lesbar sein kann ...
.cpp
Datei haben.inline
.inline
lockert nur die eine Definitionsregel, die notwendig ist, wenn eine andere Übersetzungseinheit verwendetClazz
Antworten:
C ++ ist objektorientiert in dem Sinne, dass es das objektorientierte Paradigma für die Softwareentwicklung unterstützt.
Anders als in Java zwingt C ++ Sie jedoch nicht dazu, Funktionsdefinitionen in Klassen zu gruppieren: Die Standardmethode zum Deklarieren einer Funktion in C ++ besteht darin, nur eine Funktion ohne Klasse zu deklarieren.
Wenn Sie stattdessen von Methodendeklaration / -definition sprechen, besteht die Standardmethode darin, nur die Deklaration in eine Include-Datei (normalerweise benannt
.h
oder.hpp
) und die Definition in eine separate Implementierungsdatei (normalerweise benannt.cpp
oder.cxx
) zu legen . Ich bin damit einverstanden, dass dies in der Tat etwas ärgerlich ist und einige Überschneidungen erfordert, aber so wurde die Sprache entworfen.Für schnelle Experimente und Einzeldateiprojekte würde alles funktionieren ... aber für größere Projekte ist diese Trennung praktisch erforderlich.
Hinweis: Auch wenn Sie Java kennen, ist C ++ eine völlig andere Sprache ... und diese Sprache kann nicht durch Experimentieren erlernt werden. Der Grund ist, dass es eine ziemlich komplexe Sprache mit vielen Asymmetrien und scheinbar unlogischen Entscheidungen ist, und vor allem, wenn Sie einen Fehler machen, gibt es keine "Laufzeitfehler-Engel", die Sie wie in Java retten könnten ... aber es gibt stattdessen " undefinierte Verhaltensdämonen ".
Der einzig vernünftige Weg, um C ++ zu lernen, ist das Lesen ... egal wie klug Sie sind, Sie können nicht erraten, was das Komitee entschieden hat (tatsächlich ist es manchmal sogar ein Problem, klug zu sein, da die richtige Antwort unlogisch und eine Folge der Geschichte ist Erbe.)
Wählen Sie einfach ein oder zwei gute Bücher aus und lesen Sie sie vollständig durch.
quelle
Die erste definiert Ihre Mitgliedsfunktion als Inline-Funktion , die zweite nicht. Die Definition der Funktion befindet sich in diesem Fall im Header selbst.
Die zweite Implementierung würde die Definition der Funktion in die cpp-Datei einfügen.
Beide sind semantisch unterschiedlich und es ist nicht nur eine Frage des Stils.
quelle
Die Funktionsdefinition ist außerhalb der Klasse besser. Auf diese Weise kann Ihr Code bei Bedarf sicher bleiben. Die Header-Datei sollte nur Deklarationen enthalten.
Angenommen, jemand möchte Ihren Code verwenden, können Sie ihm einfach die .h-Datei und die .obj-Datei (nach dem Kompilieren erhalten) Ihrer Klasse geben. Er benötigt die CPP-Datei nicht, um Ihren Code zu verwenden.
Auf diese Weise ist Ihre Implementierung für niemanden sichtbar.
quelle
Die Methode "Innerhalb der Klasse" (I) entspricht der Methode "Außerhalb der Klasse" (O).
(I) kann jedoch verwendet werden, wenn eine Klasse nur in einer Datei (innerhalb einer CPP-Datei) verwendet wird. (O) wird verwendet, wenn es sich in einer Header-Datei befindet. CPP-Dateien werden immer kompiliert. Header-Dateien werden kompiliert, wenn Sie #include "header.h" verwenden.
Wenn Sie (I) in einer Header-Datei verwenden, wird die Funktion (Fun1) jedes Mal deklariert, wenn Sie #include "header.h" einfügen. Dies kann dazu führen, dass dieselbe Funktion mehrmals deklariert wird. Dies ist schwieriger zu kompilieren und kann sogar zu Fehlern führen.
Beispiel für die korrekte Verwendung:
Datei1: "Clazz.h"
Datei2: "Clazz.cpp"
Datei3: "UseClazz.cpp"
Datei4: "AlsoUseClazz.cpp"
Datei5: "DoNotUseClazzHeader.cpp"
quelle
Elementfunktionen können innerhalb der Klassendefinition oder separat mit dem Bereichsauflösungsoperator :: definiert werden. Durch das Definieren einer Elementfunktion innerhalb der Klassendefinition wird die Funktion inline deklariert, auch wenn Sie den Inline-Bezeichner nicht verwenden. Sie können also entweder die Volume () - Funktion wie folgt definieren:
Wenn Sie möchten, können Sie dieselbe Funktion außerhalb der Klasse mit dem Bereichsauflösungsoperator :: wie folgt definieren
Hier ist nur wichtig, dass Sie den Klassennamen kurz vor dem Operator :: verwenden müssen. Eine Elementfunktion wird mit einem Punktoperator (.) Für ein Objekt aufgerufen, bei dem Daten, die sich auf dieses Objekt beziehen, nur wie folgt bearbeitet werden:
(von: http://www.tutorialspoint.com/cplusplus/cpp_class_member_functions.htm ) sind beide Möglichkeiten legal.
Ich bin kein Experte, aber ich denke, wenn Sie nur eine Klassendefinition in eine Datei einfügen, spielt das keine Rolle.
Wenn Sie jedoch so etwas wie eine innere Klasse anwenden oder eine Definition für mehrere Klassen haben, ist die zweite schwer zu lesen und zu pflegen.
quelle
Die erste muss in die Header-Datei eingefügt werden (in der sich die Deklaration der Klasse befindet). Die zweite kann eine beliebige Stelle sein, entweder der Header oder normalerweise eine Quelldatei. In der Praxis können Sie kleine Funktionen in die Klassendeklaration einfügen (wodurch diese implizit inline deklariert werden, obwohl letztendlich der Compiler entscheidet, ob sie inline sind oder nicht). Die meisten Funktionen haben jedoch eine Deklaration im Header und die Implementierung in einer CPP-Datei, wie in Ihrem zweiten Beispiel. Und nein, ich sehe keinen Grund, warum dies weniger lesbar wäre. Ganz zu schweigen davon, dass Sie die Implementierung für einen Typ tatsächlich auf mehrere CPP-Dateien aufteilen können.
quelle
Eine Funktion, die innerhalb einer Klasse definiert ist, wird standardmäßig als Inline-Funktion behandelt. Ein einfacher Grund, warum Sie Ihre Funktion außerhalb definieren sollten:
Ein Konstruktor der Klasse sucht nach virtuellen Funktionen und initialisiert einen virtuellen Zeiger, um auf die richtige VTABLE oder die virtuelle Methodentabelle zu verweisen , ruft den Konstruktor der Basisklasse auf und initialisiert Variablen der aktuellen Klasse, sodass tatsächlich einige Arbeiten ausgeführt werden.
Die Inline-Funktionen werden verwendet, wenn die Funktionen nicht so kompliziert sind und der Overhead des Funktionsaufrufs vermieden wird. (Der Overhead beinhaltet einen Sprung und eine Verzweigung auf Hardwareebene.) Und wie oben beschrieben, ist der Konstruktor nicht so einfach zu betrachten wie Inline.
quelle