1

我有这两个简单的文件,它们定义了一个带有 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() 函数声明为静态,问题就解决了。但为什么?

我知道 .h 文件包含在 .cpp 文件中,然后编译(到翻译单元中)并且静态变量和函数对它们包含的整个翻译单元都是可见的,但是为什么程序不起作用没有“静态”关键字?函数 tryME 应该在类之外是“全局的”,因此是可见的,不是吗?调用是否在 tryME() 之前放置了“this->”?

4

3 回答 3

1

这:

inline void tryME()
{

}

否则,您将违反单一定义规则

在头文件中定义非inline方法将导致它被包含该头文件的所有翻译单元导出,因此错误。

于 2012-04-10T21:53:11.340 回答
1

它确实是可见的。它在每个加载头文件的文件中作为单独的定义可见,因此在链接时,链接器面临多个同名的函数,并正确地抱怨它不知道您打算使用哪个函数。

不要在头文件中定义函数。声明它们是好的;定义它们,不是那么多。

于 2012-04-10T21:55:04.617 回答
1

您可以在头文件和源文件中分离函数声明和定义。在您的情况下,您可以将 tryMe() 定义从“myclass.h”移动到“myclass.cpp”,并在“myclass.h”中仅保留 tryMe() 的声明。其他方法是使用“内联”关键字,正如其他答案中已经提到的那样。

于 2012-04-11T13:28:13.343 回答