3

私はヘッダーファイルなどを使用するのは初めてですが、前学期はすべてを1つの巨大な(恐ろしい:p)ファイルで行いました...

私はしてはいけないことをしていますか?プログラムを実行しようとすると、次のような結果になります。

1>  LINK : ~~~\CSC 161\Accounting Assignment\Debug\Accounting Assignment.exe not found or not built by the last incremental link; performing full link
1>driver.obj : error LNK2005: "class std::basic_ifstream<char,struct std::char_traits<char> > welcomeFile" (?welcomeFile@@3V?$basic_ifstream@DU?$char_traits@D@std@@@std@@A) already defined in statistics.obj
1>~~~~\CSC 161\Accounting Assignment\Debug\Accounting Assignment.exe : fatal error LNK1169: one or more multiply defined symbols found
1>

統計.h:

#ifndef _STATISTICS_INTERFACE_
#define _STATISTICS_INTERFACE_
...
#include<fstream>

using namespace std;
ifstream  welcomeFile;   //if I comment this out, it compiles

class Stats
{
...blah...
};

void welcome();
void pause();
void printFile(ifstream &inFile);

#endif

統計.cpp:

#include "statistics.h"

...working functions...

void welcome()
{
    system("CLS");
    welcomeFile.open("about.txt");
    printFile(welcomeFile);
    welcomeFile.close();
    pause();
}

エラーは、何かが 2 回定義されようとしているように見えますが、#ifndef はそれを設定するはずだったので、まだ定義されていない場合にのみ定義されていると思いましたか? これは、welcomeFile を宣言した唯一の場所です ...

4

2 に答える 2

6

ヘッダー ファイルでオブジェクトを定義し、1 つの定義規則に違反したためです。

ヘッダー ファイルでオブジェクトを定義しないでください。

ヘッダー ガードは、前処理中にヘッダーの内容が同じ 翻訳単位に複数回含まれることを防ぎます。それらは、コンテンツが異なる翻訳単位に含まれることを妨げません。このヘッダー ファイルを別の翻訳単位に含めると、これらの単位のそれぞれにこのオブジェクトの定義が含まれます。
コンパイラは、各翻訳単位を個別にコンパイルして個別のオブジェクト ファイル ( .o ) を生成します。これらの .o ファイルのそれぞれに、このオブジェクト定義のコピーが含まれます。リンカーが生成時にオブジェクト/シンボル名にリンクしようとすると.exe、同じオブジェクト/シンボルの複数の定義が検出されるため、どれにリンクするかについて混乱が生じます。この問題を回避するために、標準では、同じエンティティの複数の定義を禁止する1 つの定義規則 (ODR) 。
ご覧のとおり、オブジェクト定義をヘッダー ファイルに含め、そのヘッダー ファイルを複数の翻訳単位に含めると、ODR に違反します。

externグローバル オブジェクトを使用する場合は、それを として宣言し、1 つのソース ファイルで定義する必要があります。

よく読んでください:
エラー LNK2005、既に定義されていますか?

于 2013-01-25T05:52:37.803 に答える
2

その定義を .cpp ファイルに入れる必要があります。そうしないと、この .h ファイルを含むすべてのファイルにこの変数の定義があり、リンク中に最終的に衝突します。

psusing namespace std;ヘッダーに入れることは悪いと見なされます。

于 2013-01-25T05:52:48.033 に答える