Wie verwenden Sie ordnungsgemäß Namespaces in C ++?
Ich komme aus einem Java-hintergrund, wo Pakete verwendet werden, keine namespaces. Ich bin es gewohnt, putting-Klassen, die zusammenarbeiten, um ein komplettes Objekt in Pakete und dann wiederverwenden Sie später aus diesem Paket. Aber jetzt arbeite ich in C++.
Wie verwendet man namespaces in C++? Erstellen Sie einen einzigen namespace für die gesamte Anwendung, oder Sie erstellen Namensräume für die wichtigsten Komponenten? Wenn ja, wie schaffen Sie Objekte, die von Klassen in anderen namespaces?
InformationsquelleAutor der Frage Marius | 2008-09-03
Du musst angemeldet sein, um einen Kommentar abzugeben.
Namespaces als Pakete im wesentlichen. Sie kann z.B. so verwendet werden:
Dann in code:
Hoffe, das hilft.
Oder, wenn Sie möchten, verwenden Sie immer einen bestimmten namespace, können Sie dies tun:
Edit: nach, was bernhardrusch hat gesagt, ich neigen nicht dazu, verwenden Sie die "using namespace x" syntax überhaupt, ich in der Regel explizit den namespace anzugeben, wenn die Instanziierung meine Objekte (also das erste Beispiel habe ich gezeigt).
Und als Sie fragte unten, Sie können so viele namespaces, wie Sie möchten.
InformationsquelleAutor der Antwort Mark Ingram
Um nicht zu sagen alles, was Mark Ingram schon sagte, ein kleiner Tipp für die Verwendung von namespaces:
Vermeiden Sie die "using namespace" - Anweisung im header-Dateien - dies öffnet den namespace für alle Teile des Programms, mit dem import dieser header-Datei. In Umsetzung Dateien (*.cpp) ist dies normalerweise kein grosses problem - obwohl ich lieber auf eine "using namespace" Richtlinie über die Funktion Ebene.
Ich denke namespaces werden meist verwendet, um Namenskonflikte zu vermeiden - nicht unbedingt organisieren Sie Ihre code-Struktur. Ich würde organisieren C++ - Programme vor allem mit header-Dateien /Datei-Struktur.
Manchmal namespaces werden in größere C++ - Projekte zu verbergen Implementierungsdetails.
Zusätzlicher Hinweis auf die using-Direktive:
Einige Menschen bevorzugen die Verwendung von "using" - nur für einzelne Elemente:
InformationsquelleAutor der Antwort bernhardrusch
Vincent Robert Recht in seinem Kommentar Wie gehen Sie richtig verwenden namespaces in C++?.
Using namespace
Namespaces verwendet werden, zumindest, um zu vermeiden, den Namen Kollision. In Java ist dies erzwungen durch die "org.domain" idiom (da soll man nicht verwenden, alles andere als seine/Ihre eigenen domain-Namen).
In C++, Sie könnten ein namespace, um alle den code in dein Modul. Zum Beispiel für ein Modul MyModule.dll Sie konnte seinen code den namespace MyModule. Ich habe sonst jemand mit MeineFirma::MyProject::MyModule. Ich denke, das ist übertrieben, aber alles in allem, scheint es korrekt zu mir.
Mit "mit"
Verwendung verwendet werden, sollten mit großer Sorgfalt, weil es effektiv zu importieren, eine (oder alle) Symbole aus einem namespace in Ihrem aktuellen namespace.
Dies ist böse, dies zu tun in einer header-Datei, weil Ihr Kopf wird, belasten Sie jede Quelle, einschließlich (es erinnert mich an Makros...), und sogar in einer Quellcode-Datei, schlechter Stil, außerhalb einer Funktion Gültigkeitsbereich, weil es importiert im globalen Gültigkeitsbereich die Symbole aus dem Namensraum.
Sicherste Art und Weise zu verwenden, "mit" ist der import der Symbole auswählen:
Werden Sie sehen, eine Menge von "using namespace std ;" in tutorial oder Beispiel-codes. Der Grund ist die Verringerung der Zahl der Symbole, um das Lesen zu erleichtern, nicht, weil es ist eine gute Idee.
"using namespace std ;" ist entmutigt von Scott Meyers (ich weiß nicht mehr genau, in welchem Buch, aber ich kann ihn finden, wenn nötig).
Namespace Zusammensetzung
Namespaces sind mehr als die Pakete. Ein weiteres Beispiel finden Sie in Bjarne Stroustrup "Die C++ Programmiersprache".
In der "Special Edition", bei 8.2.8 Namespace Zusammensetzung, er beschreibt, wie können Sie Zusammenführen von zwei namespaces AAA und BBB in ein anderes namens CCC. Also CCC wird ein alias für beide AAA und BBB:
Könnte man auch importieren und wählen Sie Symbole aus unterschiedlichen namespaces, erstellen Sie Ihre eigenen benutzerdefinierten namespace-Schnittstelle. Ich habe noch zu finden, einen praktischen nutzen, aber in der Theorie, es ist cool.
InformationsquelleAutor der Antwort paercebal
Ich sehe keine Erwähnung von ihm in den anderen Antworten, also hier meine 2 Kanadische cents:
Auf die "using namespace" - Thema, eine nützliche Anweisung ist die namespace-alias, so dass Sie "umbenennen" können Sie einen namespace normalerweise geben Sie einen kürzeren Namen. Zum Beispiel, anstatt:
können Sie schreiben:
InformationsquelleAutor der Antwort Éric Malenfant
Hören nicht auf, jeden Menschen, der Ihnen mitteilt, dass namespaces sind nur Namen-Räume.
Sind Sie wichtig, weil Sie als durch den compiler zu gelten, das interface-Prinzip. Grundsätzlich lässt sich an einem Beispiel erklären:
Wenn Sie etwas drucken wollte, Ein a-Objekt, der code wäre dieser hier:
Beachten Sie, dass wir nicht explizit erwähnt wird der Namensraum beim Aufruf der Funktion. Dies ist das interface-Prinzip: C++ betrachten Sie eine Funktion, die einen Typ als argument nicht als Teil der Schnittstelle, die für diesen Typ, so dass keine Notwendigkeit, um den namespace angeben, da der parameter bereits implizit den Namensraum.
Nun, warum ist dieses Prinzip wichtig? Sich vorstellen, dass die Klasse Einen Autor nicht eine Funktion print() für diese Klasse. Sie müssen angeben, dass Sie selbst einer. Wie Sie ein guter Programmierer sind, definieren Sie diese Funktion in Ihrem eigenen namespace, oder vielleicht in den globalen Namensraum.
Und der code beginnen können, ruft die print () - Funktion, wo Sie wollen. Stellen Sie sich nun vor, dass Jahre später, der Autor entscheidet, um eine print () - Funktion besser als deins, denn er kennt das Innenleben seiner Klasse und kann eine bessere version als die ihrige.
Dann C++ Autoren haben sich entschieden, dass seine version der print () - Funktion sollte verwendet werden, anstelle der in einem anderen Namensraum zu achten, das interface-Prinzip. Und dass dieses "upgrade" von der print () - Funktion sollte so einfach wie möglich, was bedeutet, dass Sie nicht haben, zu ändern, jeder Aufruf der Funktion print (). Das ist, warum "interface-Funktionen" (Funktion in der gleichen Namensraum einer Klasse) aufgerufen werden kann ohne die Angabe des namespace in C++.
Und das ist, warum sollten Sie ein C++ - namespace als "Schnittstelle", wenn Sie einen verwenden, und beachten Sie die interface-Prinzip.
Wenn Sie wollen eine bessere Erklärung für dieses Verhalten, können Sie sich an das Buch Exceptional C++ von Herb Sutter
InformationsquelleAutor der Antwort Vincent Robert
Eigentlich boost verwendet, Tonnen von namespaces, in der Regel jeden Teil von boost hat seinen eigenen Namensraum für das Innenleben und dann kann nur die öffentliche Schnittstelle in der top-level-namespace boost.
Ich persönlich denke, dass, je größer eine code-Basis wird, desto wichtiger namespaces werden, sogar innerhalb einer einzigen Anwendung (oder Bibliothek). Bei der Arbeit setzen wir die einzelnen module unserer Anwendung wird in einem eigenen namespace.
Anderen Verwendung (kein Wortspiel beabsichtigt) von namespaces, die ich benutze eine Menge ist der anonyme namespace:
Dies ist im Grunde das gleiche wie:
Mithilfe einer anonymen namespace (statt statischen) ist jedoch die empfohlene Methode für code und Daten werden nur innerhalb der aktuellen compilation unit in C++.
InformationsquelleAutor der Antwort
Beachten Sie auch, dass Sie hinzufügen können, um einen namespace. Dies ist an einem Beispiel verdeutlichen, was ich meine ist, dass können Sie haben:
in eine Datei
square.h
, undin eine Datei
cube.h
. Dies definiert den einzigen namespaceMyNamespace
(das heißt, Sie definieren einen einzigen namespace über mehrere Dateien).InformationsquelleAutor der Antwort OysterD
In Java:
In C++:
Und der Verwendung von Java:
Und C++:
Auch, vollständige Namen sind "somepackge.SomeClass" für Java und "somenamespace::SomeClass" für C++. Mit diesen Konventionen können Sie organisieren, wie Sie verwendet werden, um in Java, einschließlich passenden Ordner-Namen für Namensräume. Die Ordner->Paket-und Datei->Klasse Anforderungen gibt es nicht, obwohl, so können Sie die Namen Ihrer Ordner und Klassen unabhängig voneinander Pakete und namespaces.
InformationsquelleAutor der Antwort Staale
Können Sie auch enthalten die "using namespace ..." innerhalb einer Funktion Beispiel:
InformationsquelleAutor der Antwort Shadow2531
@marius
Ja, Sie können mehrere namespaces gleichzeitig, zB:
[Feb. 2014 -- (Ist es wirklich schon so lange?): In diesem bestimmten Beispiel ist jetzt zweideutig, als Joey Punkte unten. Boost und std:: jetzt haben jeweils einen shared_ptr.]
InformationsquelleAutor der Antwort Adam Hollidge
Generell, ich erstellen Sie einen namespace für einen Körper, der code, wenn ich glaube, dass es vielleicht sein könnte, Funktion oder Typ-Namen Konflikte mit anderen Bibliotheken. Es hilft auch, um die Hersteller-code, ala boost:: .
InformationsquelleAutor der Antwort Adam Hollidge
Ich lieber mit einer top-level-namespace für die Anwendung und sub-namespaces, die für die Komponenten.
Dem Weg können Sie die Verwendung von Klassen aus anderen namespaces ist überraschenderweise sehr ähnlich wie in java.
Sie können entweder "use NAMESPACE" das ist ähnlich wie ein "import PACKAGE" - Anweisung, z.B. mit std. Oder Sie geben das Paket als Präfix der Klasse-getrennt durch "::", z.B. std::string. Dies ist ähnlich zu "java.lang.String" in Java.
InformationsquelleAutor der Antwort dmeister
Beachten Sie, dass ein namespace in C++ ist wirklich nur ein name Platz. Sie bieten keine der Kapselung, tun Pakete in Java, so dass Sie wahrscheinlich nicht verwenden Ihnen so viel.
InformationsquelleAutor der Antwort Kristopher Johnson
Ich habe C++ - namespaces, die die gleiche Art, wie ich in C#, Perl, etc. Es ist nur eine semantische Trennung der Symbole zwischen standard-Bibliothek-Sachen, Dritter Zeug, und meine eigenen code. Ich würde meine eigene app in einem namespace, dann eine wiederverwendbare Bibliothek Komponente, die in einem anderen namespace für die Trennung.
InformationsquelleAutor der Antwort spoulson
Ein weiterer Unterschied zwischen java und C++, ist, dass in C++, die namespace-Hierarchie muss nicht mach das Dateisystem-layout. So ich neigen dazu, eine ganze wiederverwendbare Bibliothek in einem einzigen namespace und Subsysteme innerhalb der Bibliothek in Unterverzeichnissen:
Ich würde nur die Subsysteme in geschachtelten namespaces, wenn man die Möglichkeit von Namenskonflikten.
InformationsquelleAutor der Antwort KeithB