我有这两个简单的文件定义了一个带有tryME函数的C ++类
______myclass.h________________
#pragma once
void tryME()
{
}
class myclass
{
public:
myclass(void);
myclass(void);
void callTryME();
};
_________myclass.cpp____________
#include "myclass.h"
myclass::myclass(void)
{
}
myclass::~myclass(void)
{
}
void myclass::callTryME()
{
tryME();
}
这给出了错误
1> myclass.obj:错误LNK2005:“void __cdecl TryME(void)” (?TryME @@ YAXXZ)已在tryout.obj中定义1> C:\ tryout.exe:致命 错误LNK1169:找到一个或多个多重定义的符号
如果我将tryME()函数声明为static,则问题就解决了。但为什么呢?
我知道.h文件包含在.cpp文件中,然后编译(转换为翻译单元),静态变量和函数对于它们包含的整个翻译单元是可见的,但为什么不程序工作没有“静态”关键字?函数tryME应该是类外的“全局”因此可见,是不是正确的?通话是否发出“this->”在tryME()之前?
答案 0 :(得分:1)
此:
inline void tryME()
{
}
否则,您正在违反一个定义规则。
在头文件中定义非inline
方法将导致所有包含该标头的翻译单元导出该方法,从而导致错误。
答案 1 :(得分:1)
确实可见。它在每个加载头文件的文件中作为单独的定义可见,因此在链接时链接器面临着具有相同名称的多个函数,并且正确地抱怨它不知道您打算使用哪个函数使用。
不要在头文件中定义函数。宣布它们是好的;定义它们,而不是那么多。
答案 2 :(得分:1)
您可以在头文件和源文件中分隔函数声明和定义。在您的情况下,您可以将tryMe()定义从“myclass.h”移动到“myclass.cpp”,并在“myclass.h”中仅保留tryMe()的声明。其他方法是使用“内联”关键字,正如其他答案中已经提到的那样。