2016-03-21 21 views
1

Iは、次のヘッダーを持っている:私は、コンパイルされたとき名前空間内の関数の宣言と定義?

#ifndef MY_H_ 
#define MY_H_ 

namespace A { 
void f() { 
// do something 
} 
} 
#endif 

しかし、私は):: Fを(複数の定義のようなエラーを得ました。私は#ifndefチェックが1翻訳単位で重複する定義を避けるのに十分だと考えました。多分私は何かが恋しいですか?

ありがとうございます。

+2

を使用すると、複数の定義の問題は、*複数の*翻訳単位にappertainという事実を逃している、いない1つの翻訳単位に。 –

+0

@KerrekSBあなたの迅速な対応に感謝します。はい、私はあなたが意味するものを参照してください。私は問題を避けるために静的にすることができます。インラインも私のコンパイラで動作します。しかし、インラインはコンパイラのヒントにすぎないので、コンパイラはそれを無視して、複数の定義で終わります。または、コンパイラはこの場合インラインを無視しないことが保証されていますか? – Hei

+0

本当の答えはヘッダーに定義を入れることではありません。次に、複数の定義を取得しないでください! –

答えて

2

は、関数定義の前にinline指定子を追加します。

#ifndef MY_H_ 
#define MY_H_ 

namespace A { 
inline void f() { 
// do something 
} 
} 
#endif 
+0

私のコンパイラではInlineが動作します。しかし、インラインはコンパイラのヒントにすぎないので、コンパイラはそれを無視して、複数の定義で終わります。または、コンパイラはこの場合インラインを無視しないことが保証されていますか? – Hei

+0

上のリンクの説明の第1のポイントに従う: "1)インライン関数の定義は、異なる変換単位に現れる限り、プログラム内に複数の定義が存在する可能性があります。複数のソースファイルに#includeされているヘッダファイル内にあります。 "コンパイラの最適化ヒントとしてのインラインは廃止されました。 – pmed

+0

お返事ありがとうございます。つまり、新しいC++標準(C++ 11またはC++ 14)では、コンパイラはインラインでヒントを取るのではなく、インラインで正しく処理する必要がありますか? – Hei

0

ヘッダーファイルに関数を宣言して、関数をcppファイルで定義する必要があります。このヘッダーファイルを複数の翻訳単位(可能性が最も高い)から含めると、異なる翻訳単位で複数の実装が利用可能になります。このヘッダーを含む各cppファイルの実装はfになります。このようにして、fを呼び出す場合は、あいまいです。実装をcppファイルに入れることで、その方法でリンクして使用することができます。しかし、それを明確にする実装は1つしかありません。

だから、あなたのヘッダファイルは次のようになります。

#ifndef MY_H_ 
#define MY_H_ 

namespace A 
{ 
    void f(); // declaration only 
} 

#endif 

とソースファイル:

#include "myHeader.h" 

namespace A 
{ 
    void f() 
    { 
     // some implementation 
    } 
} 

その後、あなたは問題ないはずです。あなたは通常、あなたのすべての機能でそれを行います。唯一の例外はinline関数/メソッドまたはテンプレートですが、これはこの質問の範囲を超えています。

関連する問題