Klasse VERSUS-Namespace ODER Klasse UND Namespace? [geschlossen]

Klasse und Namespace?

Bei dieser Frage handelt es sich um ein Muster, das ich immer häufiger benutze: Eine Klasse und einen Namespace für verwandte Konzepte. Ich denke, dies ist hauptsächlich auf C ++ - Sprachartefakte zurückzuführen, aber nicht vollständig.

Ich nehme an, die Frage der obersten Ebene lautet: Ist das eine gute Idee? Haben Sie eine Klasse und einen Namespace für verwandte Konzepte?

Frage der unteren Ebene:

Wie geht das am besten?

Im Namespace verschachtelte Klasse ?:

namespace Foo_Namespace {
   class Foo_Class {
       ...
   };
}

Oder getrennt, Peer, Klasse und Namespace ?:

class Foo_Class {
    ...
};
namespace Foo_Namespace {
   // non-class free functions, etc.
}

Ich muss zugeben, dass ich mich dazu neige, die Klasse im Namespace zu verschachteln. Auch wenn es zu hässlichen Namen führt. Aber selbst wenn ich das tue, welche Namenskonventionen sollte ich verwenden:

Das Folgende ist zu lang und führt zu wirklich hässlichen Namen Foo_Namespace :: Foo_Class

namespace Foo_Namespace {
   class Foo_Class {
       ...
   };
}

Es ist nicht erforderlich, Suffixe oder Indikatoren im Namen zu verwenden:

namespace Foo {
   class Foo {
       ...
   };
}

Aber dann bin ich mir unsicher, wenn ich mir Foo :: bar () anschaue, ob das eine freie Funktionsleiste im Namespace :: Foo, dh :: Foo :: bar (), oder eine Member-Funktion in der Klasse Foo im Namespace ist :: Foo :: Foo :: bar ().

Und Namen wie :: Foo :: Foo :: bar sind immer noch nicht, ähm, nett.

Derzeit mache ich

Es ist nicht erforderlich, Suffixe oder Indikatoren im Namen zu verwenden:

namespace Foo_ns {
   class Foo {
       ...
   };
}

hauptsächlich, weil ich normalerweise zuerst die Klasse erstelle und später merke, dass ein Namespace schön wäre.

Ich frage mich, ob ich eine Namenskonvention wiederbeleben soll, die ich seit Jahren nicht mehr verwendet habe: _c für Klasse, _ns für Namespaces:

namespace Foo_ns {
   class Foo_c {
       ...
   };
}

Einzelheiten:

Ich werde nicht wiederholen, was ich oben gesagt habe, aber ich werde ein bisschen mehr hinzufügen.

Der praktischste Grund, den ich kenne, um einen Namespace zusätzlich zu einer Klasse zu verwenden, besteht darin, dass Sie Deklarationen freier Funktionen in einem Namespace weiterleiten dürfen, aber einige Methoden einer Klasse nicht weiterleiten dürfen. Das heißt bei einer klasse muss man alles oder nichts deklarieren. Während mit freien Funktionen im Allgemeinen und freien Funktionen in Namespaces im Besonderen, können Sie es stückweise deklarieren. Teile können in verschiedenen Header-Dateien deklariert werden. Anstatt eine massive Nur-Header-Bibliothek für eine massive Klasse einzuschließen, können Sie Forward-Deklarationen für nur eine oder zwei Funktionen verwenden. Usw.

(Siehe zum Beispielhttp://google-styleguide.googlecode.com/svn/trunk/cppguide.xml#Forward_Declarations, obwohl Google netto gegen Forward-Deklarationen verstößt, anstatt einen Header einzuschließen.)

Ein weiterer Grund ist, dass ein Namespace es ermöglicht, die Klasse selbst klein zu halten.

Der größte Vorteil einer Klasse besteht darin, dass eine Klasse an eine Vorlage übergeben werden kann, ein Namespace jedoch nicht.

Ich bevorzuge es, die Klasse im Namespace Foo_ns / Foo_ns :: Foo_c zu verschachteln, anstatt sie als Peers Foo_ns / Foo_c zu haben, da eine Klasse häufig Hilfsklassen benötigt, z. Foo_ns / Foo_ns :: Foo_c / Foo_ns :: Foo_Helper_c. Wenn die Klasse und der Namespace gleichrangig sind, scheint es seltsam, Foo_ns / Foo_c, aber Foo_ns :: Foo_Helper_c zu haben.

Ich mag Namespaces, weil ich mit Andrei Alexandresciu einverstanden bin:http://laser.inf.ethz.ch/2012/slides/Alexandrescu/1-C++%20course%20parts%201%20and%202.pdf

 Class methods vs. free functions

 • Conventional wisdom: methods are cool, free functions are so 1960s
 • Yet:
   ◦ Free functions improve encapsulation over methods
   ◦ Free functions may be more general
   ◦ Free functions decouple better
   ◦ Free functions support conversions on their left-hand argument

  Surprising fact #2

    Making a function a method should be
    your last, not first, choice

  (c) 2012– Andrei Alexandrescu. 32 / 59

Es ist besser, freie Funktionen als Methoden in Klassen zu erstellen.

Aber manchmal müssen nur Klassen verwendet werden - z. für Vorlagen.

Namenskonvention weise

Ich habe in der Vergangenheit Foo_ns / Foo_ns :: Foo_c verwendet

Ich verwende jetzt Foo_ns / Foo_ns :: Foo

(Übrigens verwende ich normalerweise Class_Names_With_Underscores_and_Initial_Caps, nicht CamelCase.)

Wenn es Sinn macht, kann ich das Suffix _ns im Namespace entfernen - z. Dabei müssen der Namespace und die Klasse (n) nicht denselben Namen haben.

Ich mag es nicht, wenn sie den gleichen Namen haben. Betrachten Sie einen Konstruktor für eine Klasse Foo in einem Namespace foo:

:: Foo :: Foo :: Foo () vs :: Foo_ns :: Foo :: Foo ()

Letzteres ist nicht viel besser, aber etwas weniger verwirrend.

Ich denke, dass ich die Klasse normalerweise alleine erstelle, ohne sie in einem Namespace zu verschachteln. Tatsächlich füge ich wahrscheinlich ein paar statische Methoden hinzu, bevor mir klar wird, dass eine in einem Namespace verschachtelte Klasse besser wäre. In diesem Stadium kann es schwierig sein, Änderungen vorzunehmen, und manchmal entstehen Weiterleitungsfunktionen, die von der klassenstatischen Methode zur freien Funktion im Namespace weiterleiten oder umgekehrt. Dies veranlasst mich zu bedauern, dass Bot von Schritt 1 an zu einer Klasse im Namespace gesprungen ist.

Fazit

Mein aktueller BKM ist Foo_ns / Foo_ns :: Foo, d.h.

namespace Foo_ns {
   class Foo { 
   ...
   };
}

Ich würde mich über Vorschläge und Verbesserungen freuen.

Oder bin ich nur kaputt dafür?

Antworten auf die Frage(3)

Ihre Antwort auf die Frage