クラスと名前空間の両方?
この質問は、私自身がますます使用しているパターンについてです。関連する概念のクラスと名前空間の両方を持つことです。これは主にC++言語のアーティファクトによって動機付けられていると思いますが、完全ではありません。
トップレベルの質問は次のとおりだと思います。これは良い考えですか?関連する概念のクラスと名前空間の両方を持っていますか?
下位レベルの質問:
これを行うための最良の方法は何ですか?
名前空間内にネストされたクラス?:
namespace Foo_Namespace {
class Foo_Class {
...
};
}
または、個別、ピア、クラス、名前空間?:
class Foo_Class {
...
};
namespace Foo_Namespace {
// non-class free functions, etc.
}
名前空間内にクラスをネストすることに傾倒していることを認めなければなりません。それは醜い名前につながりますが。しかし、それを行ったとしても、どの命名規則を使用する必要がありますか。
以下は長すぎるため、本当に醜い名前になりますFoo_Namespace :: Foo_Class
namespace Foo_Namespace {
class Foo_Class {
...
};
}
名前にサフィックスやインジケーターを使用する必要はありません。
namespace Foo {
class Foo {
...
};
}
しかし、Foo :: bar()を見ると、それが名前空間:: Fooの無料の関数バー、つまり:: Foo :: bar()であるか、名前空間のFooクラスのメンバー関数であるかがわかりません。 :: Foo :: Foo :: bar()。
そして::Foo:: Foo :: barのような名前はまだそうではありません、うーん、いいです。
現在やっています
名前にサフィックスやインジケーターを使用する必要はありません。
namespace Foo_ns {
class Foo {
...
};
}
主な理由は、通常、最初にクラスを作成し、後で名前空間が適切であることに気付いたためです。
何年も使用していない命名規則を復活させる必要があるのではないかと思います。クラスの場合は_c、名前空間の場合は_ns:
namespace Foo_ns {
class Foo_c {
...
};
}
詳細:
上で述べたことを繰り返すことはしませんが、もう少し追加します。
クラスに加えて名前空間を使用することを私が知っている最も実際的な理由は、名前空間で自由関数の前方宣言を行うことは許可されていますが、クラスの一部のメソッドの前方宣言を行うことは許可されていないことです。つまり、クラスでは、すべてまたは何も宣言する必要があります。一般に無料の関数、特に名前空間の無料の関数では、断片的に宣言できます。パーツは、さまざまなヘッダーファイルで宣言できます。大規模なクラスの大規模なヘッダーのみのライブラリを#includeするのではなく、1つまたは2つの関数に対して前方宣言を使用できます。等。
(たとえば、 http: //google-styleguide.googlecode.com/svn/trunk/cppguide.xml#Forward_Declarationsを参照してください。ただし、Googleはヘッダーを含めるのではなく、前方宣言に反対します。)
もう1つの理由は、名前空間によってクラス自体を小さく保つことができるためです。
クラスの最大の利点は、クラスをテンプレートに渡すことができるのに対し、名前空間は渡すことができないことです。
クラスには、Foo_ns / Foo_ns :: Foo_c / Foo_ns :: Foo_Helper_cなどのヘルパークラスが必要になることが多いため、クラスをピアFoo_ns / Foo_cとして使用するのではなく、名前空間Foo_ns / Foo_ns::Foo_c内にネストすることをお勧めします。クラスと名前空間がピアである場合、Foo_ns / Foo_cがあり、Foo_ns::Foo_Helper_cがあるのは奇妙に思えます。
Andrei Alexandresciuに同意するので、名前空間が好きです: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
クラスのメソッドよりも無料の関数を作成することをお勧めします。
ただし、テンプレートなど、クラスを使用する必要がある場合もあります。
命名規則
過去にFoo_ns/Foo_ns::Foo_cを使用しました
私は今Foo_ns/Foo_ns::Fooを使用しています
(ちなみに、私はCamelCaseではなくClass_Names_With_Underscores_and_Initial_Capsを使用する傾向があります。)
理にかなっている場合は、名前空間の_nsサフィックスを削除する場合があります。たとえば、名前空間とクラスが同じ名前である必要はありません。
同じ名前にするのは嫌いです。名前空間foo内のクラスFooのコンストラクターを考えてみましょう。
:: Foo :: Foo :: Foo()vs :: Foo_ns :: Foo :: Foo()
後者はそれほど良くはありませんが、少し混乱が少なくなります。
私は通常、名前空間にネストせずに、独自にクラスを作成すると思います。実際、名前空間内にネストされたクラスの方が優れていることに気付く前に、おそらくいくつかの静的メソッドを追加します。その段階までにリファクタリングするのは苦痛かもしれません、そして私は時々転送関数を作成することになります、それはクラス静的メソッドから名前空間のfree関数に、またはその逆に転送します。これにより、ボットがステップ1から名前空間のクラスにジャンプしたことを後悔しています。
結論
私の現在のBKMはFoo_ns/Foo_ns :: Foo、つまり
namespace Foo_ns {
class Foo {
...
};
}
提案や改善をいただければ幸いです。
それとも私はこれをするために壊れていますか?