[英]Why am I getting an “Already defined” error when I declare an ifstream?
我是新手使用头文件等,上学期我们在一个巨大的(可怕的: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>
statistics.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
statistics.cpp:
#include "statistics.h"
...working functions...
void welcome()
{
system("CLS");
welcomeFile.open("about.txt");
printFile(welcomeFile);
welcomeFile.close();
pause();
}
错误看起来像是试图定义两次,但我认为#ifndef应该设置它所以它只定义了它们尚未定义的东西? 这是我宣布welcomeFile的唯一地方......
因为您在头文件中定义了对象并违反了一个定义规则 。
永远不要在头文件中定义对象!
在预处理期间,标题保护可防止标题的内容在同一 翻译单元中多次包含。 它们不会阻止内容包含在不同的翻译单元中。 当您将此头文件包含在不同的转换单元中时,每个单元都将具有此对象的定义。
编译器分别编译每个转换单元以生成单独的目标文件( .o ),每个.o文件都将具有此对象定义的副本。 当链接器在生成.exe
时尝试链接到对象/符号名称时,它会找到同一对象/符号的多个定义,从而导致混淆哪个链接到哪个。 为了避免这个问题,该标准定义了一个称为一个定义规则(ODR)的规则 ,该规则禁止同一个实体的多个定义。
如您所见,在头文件中包含对象定义,并且在多个翻译单元中包含该头文件会违反ODR。
如果要使用全局对象,则需要将其声明为extern
并将其定义在一个且只有一个源文件中。
好读:
错误LNK2005,已定义?
您应该将该定义放在.cpp文件中。 否则,包含此.h文件的每个文件都将具有此变量的定义,该变量在链接期间最终会发生冲突。
ps put using namespace std;
在你的标题中, 被认为是坏的 。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.