2010-11-18 24 views
23

以前は自分のコードに名前空間を使用していません。 (STL関数を使用する以外)なぜC++で名前空間を使用する必要がありますか?

  1. 名前の競合を避ける以外に、名前空間を使用する他の理由はありますか?
  2. 宣言と定義の両方を名前空間のスコープに囲まなければなりませんか?

答えて

10

Here(あなたの明白なことは別として)

名前空間は不連続で、翻訳単位全体に広がっている可能性があるため、実装の詳細とインタフェースを分離するためにも使用できます。

名前空間内の名前の定義は、同じ名前空間内または囲み名前空間(完全修飾名付き)のいずれかに指定できます。

2
  1. 名前の衝突が原因ではありませんか? ADLの微妙な問題は、特にオペレータの過負荷に伴うものです。

  2. これは最も簡単な方法です。また、名前の前に名前空間を付けることもできます。 my_namespace :: nameを定義します。

1
  1. 回答:あなたは新しい新しい、配置をオーバーロード、または機能を削除したい場合は、名前空間にそれらをしたいとしています。あなたが必要とするものを必要としない場合、あなたの新しいバージョンを強制的に使用する人はいません。
  2. はい
2

あなたがここにあなたのアプリケーションのための論理的に分離ユニットとして名前空間を考えると、論理的なことができ、我々はファイルにこの2つのクラスをそれぞれ入れて、2つの異なるクラスがあると手段がありますが、これらのことに注意してくださいクラスは1つのカテゴリの下で分類されるほどのものを共有します。それは名前空間を使用する強い理由の1つです。

4

より理解しやすくなります。

例:

std::func <- all function/class from C++ standard library 
lib1::func <- all function/class from specific library 
module1::func <-- all function/class for a module of your system 

はまた、あなたのシステム内のモジュールとして考えることができます。

また、(例:あなたは簡単にdoxygenの中に名前空間のエンティティを文書化することができます)書き込みのドキュメントのために役に立つことができ

見過ごされがちだ
20

一つの理由は、単純に一行のコードを変更することにより、別の上で1つの名前空間を選択するようにということです別のバージョンのプロトコル、シングルスレッド対マルチスレッドのサポート、プラットフォームXまたはYのOSサポート、コンパイルおよび実行など、別のセットの関数/変数/タイプ/定数を選択できます。異なる宣言のヘッダーを含めるか、または#defines#ifdefsというヘッダーを含めると同じ効果が得られますが、これは翻訳単位全体に大きな影響を与え、異なるバージョンをリンクすると未定義の動作が発生します。名前空間を使用すると、アクティブな名前空間内でのみ適用される名前空間を使用して選択することも、名前空間の別名を使用して選択することもできるため、別名が使用される場所にのみ適用されます。未定義の動作。これはテンプレートポリシーと同様の方法で使用できますが、その影響はより暗黙的で、自動化され、普及しています。これは非常に強力な言語機能です。


はUPDATE:marcv81さんのコメントに対処...

2つの実装とのインターフェイスを使用しないのはなぜ?

「インターフェース+の実装は、」何をしているか上記の別名に名前空間を選択し、概念的ですが、特にランタイム多型と仮想派遣意味場合:

  • を生じたライブラリや実行可能ファイルは」doesnのすべての実装を含む必要があり、実行時に選択された呼び出しを常に呼び出す必要があります。

  • コンパイラは、inlininを含む無数の最適化を使用できます。 g、デッドコード除去、および「実装」の間で異なる定数を使用することができる。アレイのサイズ -

  • 異なる名前空間が使用の同じセマンティクスをサポートしなければならないが、の場合のように関数シグネチャの正確な同じセットをサポートするように結合していない自動メモリ割り当てを可能にする代わりに、より遅いダイナミックアロケーションカスタム非メンバ関数やテンプレートを供給することができ、名前空間と仮想派遣

  • :それは仮想派遣では不可能だ(と非メンバ関数の対称演算子のオーバーロードを支援 - 例えば22 + my_typeなどmy_type + 22をサポート)

  • 異なる名前空間では、特定の目的に使用するさまざまなタイプを指定できます(例:ハッシュ関数は1つの名前空間で32ビットの値を返しますが、別の名前空間では64ビットの値を返す可能性があります)が、仮想インターフェイスにはスタティックタイプが統一されている必要があります(boost::anyまたはboost::variantまたは最悪の場合の選択上位ビットは時々意味がどこ

  • 仮想ディスパッチは、多くの場合、脂肪インタフェースと不器用なエラー処理の間の妥協が含ま:名前空間で、コンパイルを与えるだけで、それは意味をなさない名前空間の機能を提供しないようにオプション、ありますがクライアントの移植に必要な時間を実施する必要があります。

+2

C++での経験とほとんど同じくらいの経験はありませんが、それはかなり悪い思いです。なぜ2つの実装を持つインタフェースを使用しないのですか?私は名前空間でそれをする利点を見ることはできません。このコメントの可能なnaïetyをお許しください:) – marcv81

+0

@ marcv81:上記のいくつかの説明...質問/思考は常に歓迎します。乾杯。 –

+0

Mindblowing、+1。私は速度/サイズの最適化を理解しています。改善された柔軟性のために、bar()が使用されている名前空間に応じて異なる戻り値の型を持つC++ 11 "auto foo = bar()"を使用できると言っていますか?私が理解している限り、私は仕事でそれを試してみるか分からない:)私が見ることができる1つの欠点は単体テストです:私はむしろテストを実行するために1つ以上の実行可能ファイルをリンクしたいと思いますが、皆のために。それは私が#ifdefを避けるのが好きなのと同じ理由です。 – marcv81