Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/125.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 为什么我会得到一个;“已定义”;声明ifstream时出错?_C++_Visual Studio 2010_Linker Errors - Fatal编程技术网

C++ 为什么我会得到一个;“已定义”;声明ifstream时出错?

C++ 为什么我会得到一个;“已定义”;声明ifstream时出错?,c++,visual-studio-2010,linker-errors,C++,Visual Studio 2010,Linker Errors,我不熟悉使用头文件,上学期我们在一个巨大的(可怕的: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

我不熟悉使用头文件,上学期我们在一个巨大的(可怕的: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>

这些错误看起来像是要定义两次,但我想#如果ndef应该设置它,那么它只定义那些还没有定义的东西?这是我唯一声明welcomeFile…

的地方,因为您在头文件中定义了对象,并且违反了一条定义规则

永远不要在头文件中定义对象

标题防护装置防止在预处理过程中多次将标题内容包含在相同的中。它们并不阻止将内容包含在不同的翻译单元中。当您将此头文件包含在不同的翻译单位中时,每个单位都将有此对象的定义。
编译器分别编译每个翻译单元以生成一个单独的对象文件(.o),这些.o文件中的每一个都将具有此对象定义的副本。当链接器在生成
.exe
时尝试链接到对象/符号名称时,它会找到同一对象/符号的多个定义,从而导致链接到哪个对象/符号的混淆。为避免此问题,标准定义了一个称为的规则,该规则禁止对同一实体进行多个定义。
如您所见,在头文件中包含对象定义并在多个翻译单元中包含该头文件违反了ODR

如果要使用全局对象,需要将其声明为
extern
,并在一个且仅在一个源文件中定义它

读得好:

您应该将该定义放入.cpp文件中。否则,包含此.h文件的每个文件都将具有此变量的定义,这最终会在链接过程中发生冲突


p、 s.使用名称空间标准放置
在标题中,.

哦。好。我想我是误会了,应该觉得自己很愚蠢。类中的那些(没有显示?)有什么区别?@DanielBall:我猜你是指类成员,类成员在类主体中声明,没有定义。你拥有的是定义而不是声明。阿洛克,你是一位学者和绅士;这是一个非常好的书面和来源的答案,我现在明白得多了,非常感谢@丹尼尔鲍尔:谢谢你,很高兴它帮了忙:)我想我明白你的意思了。。。这篇文章听起来更像是使用名称空间,这是个坏主意吗?对于命名空间中我需要的函数,比如typedef std::string;,在头中使用typedef怎么样@DanielBall
使用命名空间std
作为毯子有点凌乱,但在
.h
中使用时会放大,因为它会包含在许多
.cpp
文件中
typedef是一种黑客行为,但是只要使用std::string`就可以做你想做的事情,正如在中所解释的,但是那篇文章甚至不鼓励在标题中这样做。。所以这取决于你。好吧,谢谢你的投入。这对一个学校项目来说并不重要,但避免一个坏习惯永远不会太早,对吧?
#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
#include "statistics.h"

...working functions...

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