2008-10-18 4 views
16

Wenn C++ Namespaces verwenden, tun Sie es vorziehen, sie explizit zu nennen, wie folgt aus:Bevorzugen Sie explizite Namespaces oder "verwenden" in C++?

std::cout << "Hello, world!\n"; 

Oder bevorzugen Sie using namespace:

using namespace std; 
cout << "Hello, world!\n"; 

Und wenn, wenn Sie die letztere bevorzugen, tun Sie erklären Verwendung im Datei- oder Funktionsumfang?

Persönlich bevorzuge ich es, sie explizit zu nennen - es ist mehr Typisierung, aber wenn ich eine Mischung von Namespaces (z. B. std und boost) verwende ich finde es besser lesbar.

Antwort

17

Ich verwende immer using namespace für Std. & Boost. Alles andere tendiere ich dazu, einen expliziten Namespace zu verwenden, es sei denn, es wird so oft verwendet, dass es den Code überflutet.

In Headern verwende ich nie using namespace, um zu vermeiden, den globalen Namespace der Quelle # including zu verschmutzen.

2

Ich verwende nur explizite Namespaces, wenn Unklarheiten bestehen. Es ist besser lesbar, aber die zusätzliche Typisierung ist zu langwierig, und Sie müssen davon ausgehen, dass andere Entwickler eine grundlegende Vertrautheit mit Standardbibliotheken haben.

Die einzigen anderen Male, die ich einen Namespace buchstabiere, sind, wenn ich es nur einmal oder zweimal benutze, wie das Hinzufügen einer schnellen Debug-Anweisung, oder wenn ich eine nicht standardmäßige Bibliothek verwende.

Normalerweise deklariere ich den Namespace im Dateibereich, aber wenn Sie Namespaces mischen, kann es sinnvoll sein, die Deklaration im Funktionsumfang näher an den Punkt zu bringen, an dem sie verwendet wird.

19

Ich verwende immer explizite. Die Schreibweise tut mir nicht weh und ich sehe deutlich, woher es kommt. Es ist nützlich, wenn Sie ein älteres Projekt haben, das Sie mit eigenen "Strings", "Vektoren" usw. verwalten müssen. Je mehr Informationen der Code mit sich bringt, desto besser.

+1

Es ist nicht weh tut, bis es eine Template-Spezialisierung, die Sie heraus verpassen, weil Sie den Namespace explizit angegeben . Ich muss zugeben, dass ich das gleiche aus Habit heraus mache, aber es ist etwas, worüber ich bewusster nach dem Lesen von Meyers "Effective C++" denke. – paxos1977

+0

Das war nur wirklich ein Problem für min und max für mich in der Praxis, weiter abgeschlagen von einem MS-Header auch eine #define min und max – paulm

4

Meine allgemeine Regel verwendet immer explizit den Namespace in Headern und verwendet normalerweise im Code. Der Grund für Ersteres liegt darin, dass es in jedem Teil der Definition explizit klarstellt, was verwendet wird, und der Grund für Letzteres besteht darin, dass es die Verwendung von Ersetzungen aus einem anderen Namensraum erleichtert, wenn dies notwendig wird. Wenn wir foo :: string anstelle von std :: string verwenden wollen, müssen wir nur den Header und die using-Anweisung aktualisieren, statt jede Instanz von std :: string durch foo :: string im Code zu ersetzen.

Natürlich ist das weniger nützlich für Klassen, die im Namespace std :: liegen, da selbst wenn Sie eine Klasse ersetzen, Sie wahrscheinlich andere in std verwenden werden, und vielleicht Ambiguitätsprobleme auftreten, aber das war nur ein Beispiel.

19

Extra Tippen ist nicht das Problem hier. Das Problem mit explizit qualifizierten Namen ist das visuelle Durcheinander. Seien wir ehrlich, C++ - Syntax ist unordentlich. Keine Notwendigkeit, dies zu verschlimmern, indem Sie unnötigerweise Namen länger machen und den Code großzügig mit :: s bestreuen.

Ich bin mit Jeff Atwood: The Best Code is No Code At All. Das ist so wahr.

Namespace Importe sind eine gute Möglichkeit, Unordnung ohne Nachteil zu reduzieren: Solange der Umfang der geöffneten Namensräume auf eine einzelne Übersetzungseinheit reduziert , Namenskonflikte, sollten sie erscheinen, leicht gelöst werden kann.

Warum explizite Namen (im Allgemeinen) lesbarer sein sollten, war für mich immer ein Rätsel. Die Leser sollten den Code im Allgemeinen gut genug kennen, um Semantik abzuleiten. Wenn nicht, muss der Code trotzdem repariert werden.


1) Corollary: keine using in Header!

+0

Ich denke, "visuelle Unordnung" ist ein seltsamer Punkt, wenn std :: so schlecht ist dann warum überhaupt C++ benutzen. – paulm

+0

@paulm Ich verstehe deine Argumentation überhaupt nicht. Es klingt witzig: Nur weil C++ im Allgemeinen ausführlich ist, heißt das nicht, dass wir unseren Code nicht verbessern können. –

1

using bei Funktionsumfang oder wenn die Funktion sehr klein ist (oft), nur explizite Namespace

4

using und using namespace sind sehr nützlich den Code besser lesbar zu machen - entfernen Unordnung.

Aber in jedem Fall, in dem es schwieriger wird herauszufinden, woher ein Symbol kommt, lehne ich den Import des gesamten Namensraums ab.

Ich versuche, den Umfang des importierten Namespaces limiit:

void bar() { 

    // do stuff without vector 

    { using std::vector; 
     // do stuff with vector 
    } 

    // do stuff without vector 
} 

Für „allgemein bekannt“ Bibliotheken, wie std, würde ich mit using namespace std wagen. Es gibt Grund zu der Annahme, dass jeder, der diesen Code liest, diese Symbole kennt.

Als eine Nebenbemerkung wird das Schlüsselwort using auch verwendet, um anzugeben, dass eine abgeleitete Klasse auch die überladenen Mitglieder ihrer Oberklasse exportiert.

class A { 
    void f(A ); 
    void f(bool); 
}; 

class B : public A { 
    using A::f; // without this, we get a compilation error in foo() 
    void f(bool); 
}; 

void foo() { 
    B b; 
    b.f(A()); // here's a compilation error when no `using` is used in B 
} 
2

Ich neige dazu, explizit die Namen zu importieren, die ich an der Spitze der CPP-Datei benötigen, so ...

mit std :: cout; mit std :: endl;

etc ...

So kann ich die Kontrolle über die Namen, die ich benutze und es ist leicht zu sehen, wo sie aus und der Code kommen wird an dem Punkt der Verwendung nicht überladen.

In den seltenen Fällen, in denen ich zwei Namen aus verschiedenen Namespaces verwende, qualifiziere ich sie vollständig am Ort der Verwendung.

ich immer voll qualifizierte Namen in Header verwenden und so gut wie nie verwenden überall ‚mit Namespace x‘ ...