C++ 为什么我会得到一个;“已定义”;声明ifstream时出错?
我不熟悉使用头文件,上学期我们在一个巨大的(可怕的:p)文件中完成了所有工作 我在做不该做的事吗?尝试运行该程序会导致以下结果: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
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();
}