简体   繁体   English

当我声明ifstream时,为什么会出现“已经定义”的错误?

[英]Why am I getting an “Already defined” error when I declare an ifstream?

I'm new to using header files and such, last semester we did everything in one giant(horrible :p) file ... 我是新手使用头文件等,上学期我们在一个巨大的(可怕的:p)文件中做了所有事情......

Am I doing something I'm not supposed to? 我在做一些我不应该做的事吗? Attempting to run the program results in the following: 尝试运行该程序会导致以下结果:

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: 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: statistics.cpp:

#include "statistics.h"

...working functions...

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

The errors look like something is trying to be defined twice, but I thought #ifndef was supposed to set it so it only defined things if they weren't already? 错误看起来像是试图定义两次,但我认为#ifndef应该设置它所以它只定义了它们尚未定义的东西? This is the only place where I declared welcomeFile ... 这是我宣布welcomeFile的唯一地方......

Because you defined the object in the header file and violated one definition rule . 因为您在头文件中定义了对象并违反了一个定义规则

Never define objects in header file! 永远不要在头文件中定义对象!

Header guards prevent the contents of the header to be included multiple times in the same translation unit during preprocessing. 在预处理期间,标题保护可防止标题的内容在同一 翻译单元中多次包含。 They do not prevent the contents to be included in different translation units. 它们不会阻止内容包含在不同的翻译单元中。 When you include this header file in different translation units, each of these units will have a definition of this object. 当您将此头文件包含在不同的转换单元中时,每个单元都将具有此对象的定义。
The compiler compiles each translation unit separately to produce a separate object file( .o ), each of those .o files will have an copy of this object definition. 编译器分别编译每个转换单元以生成单独的目标文件( .o ),每个.o文件都将具有此对象定义的副本。 When the linker tries to link to the object/symbol name at time of generating the .exe it finds multiple definitions of the same object/symbol, thereby causing confusion as to which one to link to. 当链接器在生成.exe时尝试链接到对象/符号名称时,它会找到同一对象/符号的多个定义,从而导致混淆哪个链接到哪个。 To avoid this problem the standard defines a rule known as the One defintion rule(ODR) , which forbids multiple definitions of the same entity. 为了避免这个问题,该标准定义了一个称为一个定义规则(ODR)的规则 ,该规则禁止同一个实体的多个定义。
As you see including the object definition in the header file and including that header file in multiple translation units violates the ODR. 如您所见,在头文件中包含对象定义,并且在多个翻译单元中包含该头文件会违反ODR。

If you want to use a global object, You need to declare it as extern and define it in one and only one source file. 如果要使用全局对象,则需要将其声明为extern并将其定义在一个且只有一个源文件中。

Good Read: 好读:
error LNK2005, already defined? 错误LNK2005,已定义?

You should put that definition in a .cpp file. 您应该将该定义放在.cpp文件中。 Otherwise, every file that includes this .h file will have a definition of this variable, which ultimately clash during linking. 否则,包含此.h文件的每个文件都将具有此变量的定义,该变量在链接期间最终会发生冲突。

ps putting using namespace std; ps put using namespace std; in your header, is considered bad . 在你的标题中, 被认为是坏的

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM