简体   繁体   中英

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 ...

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:

#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();
}

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? This is the only place where I declared 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. 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. To avoid this problem the standard defines a rule known as the One defintion rule(ODR) , which forbids multiple definitions of the same entity.
As you see including the object definition in the header file and including that header file in multiple translation units violates the 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.

Good Read:
error LNK2005, already defined?

You should put that definition in a .cpp file. Otherwise, every file that includes this .h file will have a definition of this variable, which ultimately clash during linking.

ps putting using namespace std; in your header, is considered bad .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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