私は実装ファイルで名前のない名前空間を使用していますか?

外部* .cppファイルにいくつかの関数(ここではクラスは含まれていません)を定義しましたが、もちろん適切な* .hファイルがあります。

* .cppファイル内の関数の中には、他の場所の* .cppファイルでのみ使用されているものがあります。彼らは* .hファイルにも言及されていません。

これらの関数を名前のない名前空間に入れるか、他の関数のすぐ隣に置かなければなりませんか?もしそうなら、私はそれらのために名前のない名前空間が必要なのでしょうか?私は問題を見ることができません。なぜなら、これらの機能は外部からアクセスできないからです。

5
@JamesMcLaughlin:C ++ 03では、 static はその目的で廃止されました。ただし、C ++ 11ではこれを非推奨にしています。しかし、 static と名前のない名前空間にあるということは、異なることを意味します。 static は内部リンケージを与えます。そのため、関数はいくつかの目的に使用できません。
追加された 著者 Fred Larson,
単に静的にしないのはなぜですか? (静的クラスメソッドではなく静的C関数の場合と同様)
追加された 著者 James McLaughlin,
@FredLarson C ++ 11で非推奨になった唯一の理由は、委員会では、使用についての心が変わったわけではなく、人々が使用をやめるのが現実的ではないと感じたからです。
追加された 著者 David Stone,
あなたの提案をありがとう。これらのソリューションのうち、静的な名前空間または名前のない名前空間が推奨または推奨されていますか?
追加された 著者 user1192880,

3 答え

そのコンパイル単位に対して本当にプライベートにしたい場合は、匿名の名前空間に入れてください。あなたがしなければ、誰かが他の場所でそれらの関数を宣言し、明示的に使用することができます。

次の例を考えてみましょう。

// library.cpp

// a "private" function here, in that it is not declared anywhere
void f() {}

namespace
{
  //same as above, except within an anonymous namespace
   void g() {}
}

// client.cpp

void f();

int main()
{
  //Can call f(), it's been declared and is now effectively "public"
   f();

  //compilation error, this has no idea what g() is, it's not declared 
  //in any scope that can be resolved here
   g();

   return 0;
}
10
追加された
これが static です。匿名の名前空間はクラスと構造体にこの機能を提供します。
追加された 著者 Clark Gaebel,
static キーワードは、コードの他の部分に存在する可能性のある他の関数との名前の衝突を防ぎますか?名前のない名前空間が使用されます。
追加された 著者 Chad,
ありがとうございました!私はその "特徴"を知らなかった。
追加された 著者 user1192880,

あなたの質問は2つに分けることができます:

1。 "どのようにグローバル機能を隠すことができますか?"

これを行う簡単な方法の1つは、関数のヘッダーをヘッダーファイルに入れるには NOT です。

//============================
// Filename: "mylibrary.hpp"
//============================
// Description:
// Utility functions.
//============================
#ifndef MYLIBRARY_H_INCLUDED
#define MYLIBRARY_H_INCLUDED
//============================

namespace MyLibrary
{
    void DoSomething();
}//namespace MyLibrary

//============================
#endif//MYLIBRARY_H_INCLUDED
//============================

フルコードファイル:

//============================
// Filename: "mylibrary.cpp"
//============================
// Description:
// Utility functions.
//============================
// self header include
#include "mylibrary.hpp"
//============================

namespace MyLibrary
{
    void DoSomethingBefore()
    {
     //...
    }

    void DoSomethingAfter()
    {
     //...
    }

    void DoSomethingConfirmed()
    {
     //...
    }

    void DoSomething()
    {
      DoSomethingBefore();
      DoSomethingConfirmed();
      DoSomethingAfter();
    }
}//namespace MyLibrary

//============================
#endif//MYLIBRARY_H_INCLUDED
//============================

これがコンパイルされると、 "mylibrary.o"または "mylibrary.obj"ファイルが作成されます。他の開発者には、 "mylibrary.hpp"と "mylibrary.obj"を追加することができますが、 "mylibrary.cpp"ファイルは必要ありません。ほとんどの "プレーンc"/"c ++"コンパイラはこのように動作します。

他の方法もあります。次のセクションを読んでください。

2。 "匿名の名前空間は、グローバルな機能を隠す良い方法ですか?"

"匿名ネームスペース"技術は、グローバル関数を隠す別の方法です。

同様の質問があります:

無名/匿名名前空間対静的関数

しかし、個人的には、このテクニックを「好きな」答えとしてはお勧めしません。

ネームスペースは、「純粋なc」または「c ++」の開始以来存在したいと望むものの1つです。しかし、 "匿名の名前空間"や "名前のない名前空間"は、使用するのが奇妙なようです。

それは何かを隠そうとするようなものだし、後で、それをどこに保管しているのか忘れてしまう。

3つの追加の提案

(a)ファイルごとにオプションの非匿名の名前空間ではなく、必須という単一の主な機能を使用することをお勧めします。ネストされた追加の内部名前空間を持つことがあります。それぞれのメイン名前空間は、同じIDを持つ必要があります。ファイル拡張子やファイルサフィックスは使用しません。

(b)匿名の名前空間を避ける。それは索引なしで倉庫に物を保管するようなものです。

(c)C ++ファイルであっても、ヘッダーファイルにファイル拡張子、つまりファイルプレフィックス(多分 ".h"または ".hpp")を使用します。標準では、c ++は "c ++"ファイルに対してファイル拡張子やファイルサフィックスを使用すべきではないが、ファイルシステムを識別したり見つけたりすることは難しいという。

がんばろう。

4
追加された

私は、外部から見たこれらの関数を静的として宣言したくないと思うでしょう。

1
追加された
「...外部から見た...」 - 何の外からですか?ヘッダー?翻訳単位は?
追加された 著者 jww,