2013-10-23 13 views
26

hereのような場所では、.hファイルと.cppファイルを含める必要があります。そうしないと、エラーが発生するためです。ですから、例えば.cppファイルを含める

main.cppに

#include <iostream> 
#include "foop.h" 

int main(int argc, char *argv[]) 
{ 
int x=42; 
std::cout << x <<std::endl; 
std::cout << foo(x) << std::endl; 
return 0; 
} 

foop.h

#ifndef FOOP_H 
#define FOOP_H 
int foo(int a); 
#endif 

foop.cpp

int foo(int a){ 
    return ++a; 
} 

作品が、私は#include "foop.cpp"#include "foop.h"を交換する場合、私はエラーを取得します(Dev C++ 4.9.9.2、Windowsを使用):

multiple definition of foo(int) 
first defined here 

なぜですか?

+0

この例は、うまくコンパイルする必要があります。不足している詳細はありますか? –

+0

あなたは.cppだけを含んでいますか?それはこの単純な場合に許されるべきです。 .hと.cppの両方を含むobvisoulyは関数を定義します –

答えて

34

preproccesorが作業を完了したときにmain.cppようになります(<>または""内部の引数がある)ファイルからすべての内容をコピーしているんので、何include

// iostream stuff 

int foo(int a){ 
    return ++a; 
} 

int main(int argc, char *argv[]) 
{ 
    int x=42; 
    std::cout << x <<std::endl; 
    std::cout << foo(x) << std::endl; 
    return 0; 
} 

fooはmain.cppに定義されていますが、定義はfoop.cppにも存在するため、関数の重複のためにコンパイラは「混乱します」。

+0

'#pragma once'ディレクティブを使って回避できると思います。 –

+2

@xorguy foop.cとfoop.hはどうやって互いを知っていますか?私はあなたの答えであなたが言っていることを理解していますが、main.cppがfooの定義についてどのように知っていますか? main.cppにはfoop.hが含まれています。whareはfooの定義ではない宣言だけです。では、main.cppはfooの定義をどのように知っていますか? –

+0

@WakanTanka正しい方法(ヘッダファイルを含む)が行われた場合、 'main.cpp'は' foo.cpp'について知りません。したがって、エラーは発生しません。これがヘッダーファイルを使用する理由です。彼の答えでは、@ xorguyは 'main.cpp'が#includeを含む例を使用しました。この場合、同じ関数が 'main.cpp'と' foo.cpp'の両方で定義されてしまうので、エラーがスローされます。 – spicypumpkin

1

あなたのプログラムは、今一度foo.cppの内側に、一度貼り/そのファイルの内容をコピーするようにコンパイラに指示などの#includeのmain.cppに

だと思うの内側に、foo機能の2つのコピーを含んでいるのであなたのコードの中に、あなたはそれゆえ、この

#include <iostream> // actually you'll get the contents of the iostream header here, but I'm not going to include it! 
int foo(int a){ 
    return ++a; 
} 

int main(int argc, char *argv[]) 
{ 
int x=42; 
std::cout << x <<std::endl; 
std::cout << foo(x) << std::endl; 
return 0; 
} 

とfoo.cpp

int foo(int a){ 
    return ++a; 
} 

のように見え、処理main.cppになってしまいます複数の定義エラー

21

.cppファイルを含めることを避ける理由はたくさんありますが、厳密には許可されていません。あなたの例はうまくコンパイルする必要があります。

問題はおそらく、main.cppとfoop.cppの両方をコンパイルしていることです。つまり、foop.cppの2つのコピーが一緒にリンクされています。リンカーは重複について不平を言っています。

4

の定義は、の宣言の間で異なります。

  • 関数と変数を異なる翻訳単位で、または同じ翻訳単位で複数回宣言することができます。関数または変数を宣言したら、その時点から関数または変数を使用できます。
  • 非静的関数または変数は、すべての翻訳単位で1回のみ定義できます。非静的項目を複数回定義すると、リンカーエラーが発生します。

ヘッダーには一般に宣言が含まれます。 cppファイルには定義が含まれています。定義を含むファイルを複数回インクルードすると、リンク時に重複が発生します。

あなたの状況では、定義はfoo.cppで、もう1つの定義はmain.cppです(foo.cppを含む)。

注:あなたがstaticするfooを変更した場合、あなたは何のリンクエラーを持っていないだろう。エラーがないにもかかわらず、これはではなく、といいます。

+0

これは私が探していたほとんどの答えです。私は文字通りC++の新機能ですから、どのようにクラスを宣言すればいいですか?ヘッダーファイルを使用する必要がありますか?次に、そのクラスを別のファイルで使用するように定義するにはどうすればよいですか?この質問を無関係に申し訳ありませんが、適切なヘルプが見つかりません:( – Hydro

+1

@TheProHands [この記事を見てください](https://www.gamedev.net/resources/_/technical/general-programming/organizing -c-r-1798)。 – dasblinkenlight

5

#include "foop.cpp"と言うときは、foop.cppの内容全体をコピーしてmain.cppに貼り付けたかのようになります。 mainfoo:あなたはmain.cppコンパイル時に

だから、コンパイラは2つの機能のための実行可能コードが含まれているmain.objを発します。

foop.cpp自体をコンパイルすると、コンパイラはを出力し、これには関数fooの実行可能コードが含まれています。

これらをリンクすると、コンパイラは関数foo(1つはmain.obj、もう1つはfoop.obj)の2つの定義を見て、複数の定義があると不平を言います。

0

One Definition Rule(おそらく)のためです。

C++では、インラインでないオブジェクトと関数はそれぞれ、正確にの1つのという定義をプログラム内に持つ必要があります。 foo(int)が定義されているファイル(CPPファイル)は、#includeによって定義され、foop.cppが#include dであるすべてのファイルと、foop.cpp自体で定義されます(foop.cppがコンパイルされていると仮定します)。

この動作を無効にするには、関数inlineを作成できますが、ここでは推奨しません。私は、CPPファイル#includeが必要であるか、または望ましい状況を見たことがありません。

何かの定義を含めることが望ましい状況があります。これは、テンプレートの宣言からテンプレートの定義を分離しようとするときに特に当てはまります。そのような場合、私は、違いを示すためにCPPではなくHPPという名前を付けます。


:「(おそらく)」私はあなたが投稿した実際のコードがエラーなしでコンパイルする必要がありますので、おそらくここで言うが、コンパイラエラー与えられ、あなたが投稿コードがではないと思わ正確にあなたがコンパイルしているコードと同じです。 「.H」メソッドを使用して

0

は 優れている。しかし、あなたが本当に.cppファイルを含めたい場合は、その後のfoo(int型)を作る静的foo.cppで

3

あなただけのヘッダファイル(複数可)を含める必要があります。

ヘッダーファイルを含めると、ヘッダーファイルで.cppファイルが自動的に検索されます。 - >このプロセスはLINKERによって実行されます。

+0

この回答は、質問に記載されている問題を完全に説明しています – pasha

+0

@pashaこの回答は、実際に同時に間違っている間にこのトピックのニュアンスを完璧に逃しています – enedil

+1

@ enedil、それを指摘してくれてありがとう、Googleで時間を過ごした後、私は今同意するが、なぜそれが、私はいくつかの他のものを学ぶことができるかもしれないことを説明してください – pasha

関連する問題