2012-02-06 3 views
5

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

* .cppファイルの一部の機能は、の中で* .cppファイルにのみ使用されます。彼らは* .hファイルにも言及されていません。

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

+0

「静的」にするのはなぜでしょうか? (静的なクラスメソッドではなく静的なC関数の場合と同じように) –

+1

@JamesMcLaughlin:C++では03静的な静的なメソッドは非推奨です。ただし、C++ 11ではこれを非推奨にしています。しかし、静的で無名の名前空間にあるということは、異なることを意味します。 'static'は内部リンケージを与えるので、関数はいくつかの目的のために使用することはできません。 –

+0

あなたの提案をありがとう。 これらのソリューションは、静的な名前空間または未使用の名前空間のいずれかですが、推奨されているか優先されていますか? – user1192880

答えて

9

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

// 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; 
} 
+0

ありがとう!私はその "特徴"を知らなかった。 – user1192880

+0

これは 'static'のためのものです。匿名の名前空間はクラスと構造体にこの機能を提供します。 –

+0

'static'キーワードは、コードの他の部分に存在する可能性のある他の関数と名前の衝突を防ぎますか?名前のない名前空間が使用されます。 – Chad

1

は、次の例を見てみましょう。

+0

*「...外から見た...」* - 何の外から?ヘッダー?翻訳単位は? – jww

4

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

1.「どのようにグローバル関数を隠すことができますか?」

ませは、ヘッダファイルに関数のヘッダを置くことで、それを行うための一つの簡単な方法:

//============================ 
// 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.「匿名の名前空間は、グローバル関数を隠す良い方法ですか?」

グローバル機能を非表示にするもう1つの方法は、「匿名ネームスペース」手法です。 「お気に入り」の答えとして

Unnamed/anonymous namespaces vs. static functions

しかし、個人的に、私はこの手法をお勧めしません、:

にも同様の問題があります。

名前空間は、「純粋なc」または「C++」の開始以来存在していたことの1つです。しかし、 "匿名の名前空間"や "名前のない名前空間"は、使用するのが奇妙なようです。

これは、何かを隠そうとするようなもので、後で、あなたはそれをどこに保存しますか。

3つの追加の提案

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

(b)匿名の名前空間は使用しないでください。それは索引なしで倉庫に物を保管するようなものです。

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

Good Luck。

関連する問題