ヘッダーとソースにC ++名前空間を作成する(cpp)


90

ヘッダーとcppファイルの両方の内容を名前空間でラップすることと、ヘッダーの内容だけをラップしてからcppファイルで名前空間使用することとの間に違いはありますか?

違いとは、問題や私が知っておく必要のあることを引き起こす可能性のある、あらゆる種類のパフォーマンスの低下やわずかに異なるセマンティクスを意味します。

例:

// header
namespace X
{
  class Foo
  {
  public:
    void TheFunc();
  };
}

// cpp
namespace X
{
  void Foo::TheFunc()
  {
    return;
  }
}

VS

// header
namespace X
{
  class Foo
  {
  public:
    void TheFunc();
  };
}

// cpp
using namespace X;
{
  void Foo::TheFunc()
  {
    return;
  }
} 

違いがない場合、推奨される形式とその理由は何ですか?

回答:


38

名前空間は、関数のシグネチャが競合しないようにマングルする方法にすぎません。最初の方法を好む人もいれば、2番目のバージョンを好む人もいます。どちらのバージョンも、コンパイル時のパフォーマンスには影響しません。名前空間は単なるコンパイル時のエンティティであることに注意してください。

名前空間の使用で発生する唯一の問題は、同じネストされた名前空間名がある場合X::X::Fooです(つまり)。これを行うと、キーワードの使用の有無にかかわらず、より多くの混乱が生じます。


56

「名前空間X」と「名前空間Xの使用」の違いは、最初の宣言では新しい宣言が名前空間の下にあるのに対し、2番目の宣言ではそうではないことです。

あなたの例では、新しい宣言はありません-したがって、違いはなく、したがって好ましい方法はありません。


それはプロジェクトとスタイルに依存します。多くの場合、モジュール内のファイルのロード用に1つのメイン名前空間があり、2番目のスタイルは理にかなっています。
ニコラスウィルソン

8

結果は同じになる可能性があるため、パフォーマンスの低下はありませんが、Foo名前空間にを入れると、Foo異なる名前空間にsがある場合に、暗黙的にあいまいさが生じます。確かに、コードfubarを入手できます。usingこの目的での使用は避けることをお勧めします。

そして、あなたは{後に迷いましたusing namespace;-)


それは}最後の締めくくりと一致するので、私はそれを迷子とは呼びません。ただし、その中括弧のペアは冗長と呼びます;)
blubberdiblub 2017年

@blubberdiblub、質問が編集されました。元のバージョンを確認した場合、それは迷子呼ばれます;-)
MichaelKrelin-ハッカー2017年

1

2番目のものもコンパイルする場合、違いはないはずです。名前空間はコンパイル時に処理されるため、実行時のアクションに影響を与えることはありません。

しかし、設計上の問題については、2番目は恐ろしいです。コンパイルしても(わからない)、まったく意味がありません。


1
コンパイルされるとは思いませんが、違いがあるからではなく、迷いがあるからです{;-)
MichaelKrelin-ハッカー2011年

違いは、それが名前空間Xで定義されている間はFoo :: TheFunc()は、グローバル名前空間で宣言されている
BERT-1月を

1

Foo :: TheFunc()は、VSの場合の正しい名前空間にありません。'void X :: Foo :: TheFunc(){}'を使用して、正しい名前空間(X)に関数を実装します。


質問は少し古いですが、これの結果が何であるか知っていますか?つまり、彼のVSケースが名前空間内の関数を宣言する方法に問題が発生しますが、名前空間の外部で関数を定義しますか?
Adam Goodwin

1

.hコンテンツのみをラップする場合は、名前空間...を使用してcppファイルに書き込む必要があります。それ以外の場合は、毎回有効な名前空間で作業します。通常、.cppファイルと.hファイルの両方をラップします。そうしないと、別の名前空間のオブジェクトを使用するリスクがあり、多くの問題が発生する可能性があります。


0

ここで正しいことは、スコープに名前空間を使用することだと思います。

namespace catagory
{
    enum status
    {
      none,
      active,
      paused
    }
};

void func()
{
    catagory::status status;
    status = category::active;
}

0

ある変数から別の変数を使用しようとしている場合は、変数を外部化してから、次のようにソースファイルで初期化することをお勧めします。

// [.hh]
namespace example
{
   extern int a, b, c;
}
// [.cc]
// Include your header, then init the vars:
namespace example
{
   int a, b, c;
}
// Then in the function below, you can init them as what you want: 
void reference
{
    example::a = 0;
}
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.