100

*.hインターフェイス宣言ファイル(または*.hpp)とその実装ファイル( )の2つのソースファイルのペアについて考えてみます*.cpp

ファイル*.hを次のようにします。

namespace MyNamespace {
  class MyClass {
  public:
    int foo();
  };
}

ソースファイルで名前空間を使用するための2つの異なる方法を見てきました。

*.cpp練習#1を示す:

#include "MyClass.h"
using namespace MyNamespace;

int MyClass::foo() { ... }

*.cpp練習#2を示す:

#include "MyClass.h"
namespace MyNamespace {

  int MyClass::foo() { ... }

}

私の質問:これら2つのプラクティスの間に違いはありますか?一方は他方よりも優れていると考えられていますか?

4

6 に答える 6

76

コードの可読性の観点から、私の意見では、この理由で#2の方法を使用する方がおそらく良いでしょう。

一度に複数の名前空間にすることができusing、その行の下に記述されたオブジェクトまたは関数は、それらの名前空間のいずれかに属することができます(名前の競合を除く)。ファイル全体をブロックにラップすることnamespaceはより明確であり、.cppファイル内でその名前空間に属する新しい関数と変数を宣言することもできます。

于 2012-05-30T12:52:08.287 に答える
58

最も明確なのは、表示しなかったオプションです。

int MyNamespace::MyClass::foo()
{
    //  ...
}

また、非常に冗長です。ほとんどの人にとっては多すぎます。using namespace少なくとも私の経験では、これは名前の競合のレセプトであり、非常に限られた範囲と場所を除いて避ける必要があるため、私は通常、あなたの#2を使用します。

于 2012-05-30T13:30:47.237 に答える
11

これら2つのプラクティスの間に違いはありますか

はい。#1と#2は、それぞれusing-directivenamespace定義の例です。この場合、これらは事実上同じですが、他の結果をもたらします。たとえば、と一緒MyClass::fooに新しい識別子を導入すると、スコープが異なります。

#1:

using namespace MyNamespace;
int x;  // defines ::x

#2:

namespace MyNamespace {
  int x;  // defines MyNamespace::x
}

一方が他方よりも優れていると考えられていますか?

#1長所:もう少し簡潔。誤って何かをMyNamespace無意識のうちに導入することはより困難です。短所:意図せずに既存の識別子を取得する可能性があります。

#2長所:既存の識別子の定義と新しい識別子の宣言の両方がに属していることをより明確にしMyNamespaceます。短所:意図せずに識別子をに導入しやすくなりMyNamespaceます。

#1と#2の両方に対する批判は、おそらくのメンバーの定義だけを気にするときに、それらが名前空間全体を参照しているということですMyNamespace::MyClass。これは手間がかかり、意図をうまく伝えません。

#1に代わる可能性のあるものは、関心のある識別子のみを含むusing宣言です。

#include "MyClass.h"
using MyNamespace::MyClass;

int MyClass::foo() { ... }
于 2016-06-01T20:57:40.070 に答える
6

また、何らかの理由でcppファイルにテンプレートの特殊化を実装することを決定し、それに依存するusing namespace場合は、次の問題が発生することも付け加えておきます。

// .h file
namespace someNameSpace
{
  template<typename T>
    class Demo
    {
      void foo();
    };
}

// .cpp file
using namespace someNameSpace;

template<typename T>
void Demo<T>::foo(){}

// this will produce
// error: specialization of 'template<class T> void someNameSpace::Demo<T>::foo()' in different namespace [-fpermissive]
template<>
void Demo<int>::foo(){}

それ以外の場合、#2の方法を適用すると、これで問題ありません。

于 2016-06-04T12:26:59.173 に答える
0

using-declarationを使用して、もう1つの方法を追加したいと思います。

#include "MyClass.h"
using MyNamespace::MyClass;

int MyClass::foo() { ... }

この方法により、クラスに多くの関数がある場合に、名前空間名を何度も入力する必要がなくなります。

于 2016-12-07T06:39:36.157 に答える
0

プラクティス#1は正しいC++コードではないと思います。このコードスニペットは::MyClass:: fooシンボルを定義します。ここで、実際の完全修飾名は:: MyNamespace :: MyClass::fooです。

名前空間について学ぶために、ドラフトのセクション7.3を読むことができます。たとえば、標準のhttp://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3690.pdf

この概念は1998年頃からかなり古いので、B.Stroustroupの標準または本を使用してそれについて学ぶことができます。

C ++言語では、名前空間は名前付きスコープです。クラス定義とは対照的に、名前空間は新しい関数を追加することができます。

「名前空間NSを使用する」構造。C ++ではusing-directiveと呼ばれ、私の練習ではいくつかの目標に使用できます。

  1. このディレクティブを別の名前空間で使用して、別の名前空間の名前を結合(混合)できます。
  2. コンパイルユニットのコンテキストでは、名前空間NS内のすべての変数に同義語を追加します。

シンボルを定義するには、2つのメカニズムを使用できます。C++ソースファイルのグローバル名前空間で操作することにより、すべての名前空間で明示的な修飾を使用できます。

または、名前空間を開いて定義を追加することもできます(練習#2)。

于 2021-08-21T15:09:35.457 に答える