我有C ++项目,它包含多个(实际上很多).cpp和.h文件。在编写头文件时,我有一个文件如下
例如MyHeaderFile.h
#ifndef _MYHEARDERFILE_H
#define _MYHEARDERFILE_H
// Here i have function defintion.
void myFunc() {cout << "my function" << endl; }
#endif
上面的文件包含在多个文件中。在编译时我得到了“myfunc”的多重定义“错误。 我期待标题只被包含一次,因为我有#ifndef检查所以我期待错误不应该被抛出。
例如,在模板的情况下,我们必须在头文件中定义,在这种情况下我们如何避免我现在面临的问题?
任何人都可以帮助我,为什么我会看到错误?我的理解是对的吗?
谢谢!
答案 0 :(得分:7)
通常,将函数声明放在头文件中,并在源文件中运行 definitions (即实际的函数体/实现)。否则,您将得到您正在看到的问题:头文件是#include
d(即替换)到多个源文件中,因此该函数最终被定义多次。这会混淆链接器,所以它会抱怨。
标头保护#ifndef ...
内容仅阻止标头多次替换到相同的源文件中。请记住,每个源文件都是完全独立于其他源文件编译的;所有#define
和其他定义都为每个定义“重置”。
一种可能的替代解决方案是将函数定义保留在头文件中,而只是将其标记为inline
(这具有消除链接器错误的副作用)。但是,就个人而言,我不会这样做。
答案 1 :(得分:0)
每个函数只能在一个翻译单元中定义一次(这称为一个定义规则,不仅适用于函数)。通过将定义放在随后包含的标题中,您违反了此规则。
您可以简单地留下声明
void myFunc();
标题中的,并在提供定义的.cpp中定义myFunc。 否则你可以内联声明你的函数。
请注意,在使用模板时,通常会引导您(与模板相关的特定问题)将定义直接放在标题中,考虑到您现在面临的问题,这可能会令人惊讶。