函数错误/头文件/内联的多重定义

Multiple definition of function error/header files/inlining

本文关键字:定义 错误 文件 函数      更新时间:2023-10-16

如果这是重复的,很抱歉,但我找到的。。。嗯,我想我也试过同样的解决方案,但没有用。无论如何,我最近尝试将我常用的随机函数的实现转移到一个单独的头文件中:我知道这些函数是如何工作的,怀疑我是否会很快更改它们,所以我认为文件越少越好(而且函数很短)。

所以,我尝试了一下。将.cpp文件的内容粘贴到一个新文件中,并添加了保护。然后把它包括进去,瞧,它起作用了。不幸的是,我把它包含了两次,发现我把同一个函数的副本分发到每个文件,因此出现了错误。(仍然有点困惑为什么会有头球后卫,因为你最终得到了一份副本,但我想确实如此)。无论如何,我在谷歌上搜索了一下(并搜索了一下),发现如果你将它们声明为内联(在这种情况下这是有意义的),那么预处理器(或者这也是链接器吗?)会做得很好。现在我把它看作一个小问题,DEFINES是文件的本地定义,还是全局定义?(也就是说,如果我在两个文件中包含一个头,并使用定义的头保护……两个文件都包含它吗?因为定义发生在不同的文件中,还是只包含一次?如果它确实包含了两次,你会得到同一函数/类/结构的多个声明(但没有定义),我认为这会引发错误,但我想它不会出现在不同文件中?)?否则,它可能不会被包括在内,也不知道它是什么。那么,重新问一下,DEFINES是文件的本地吗?)

以下是我在文件中拥有的功能被复制(认为只包含一个功能)

#ifndef RANDOM_H
#define RANDOM_H
//needed for getting system time and for random generation functions rand and srand
#include <time.h>
#include <stdlib.h>
//this function returns a random number between an inclusive range
inline int randomRange(const int & min, const int & max)
{
if (max >= min)
return ((rand() % (max+1-min))+min);
else
return ((rand() %  (min+1-max))+max);
}
#endif

然后我只在两个文件中有#includes,在这个文件上(这是"random.h")

我错过了什么?

编辑:错误消息为:

"randomRange(int const&,int const&aamp;)"|的多重定义

在休息的时候,我关闭了IDE。重新开放后,一切都修复了。显然,添加内联DID可以修复它,但与运行时的cpp文件不同,除非手动保存,否则头文件(如果没有添加到项目中)不会更新。保存后,它起了作用。对不起,各位。

当天的教训:在修复此类错误时,请确保您的文件已更新。。。

宏定义是翻译单元的本地定义:编译源文件时,预处理器扩展各种预处理器指令(#define#include等),并将结果传递给实际编译器。对每个文件执行一次,而不仅仅是一次。之所以要包含保护,是因为同一个标头很可能在同一个翻译单元中包含两次。例如,如果您有类型Point,它由类RectangleTriangle使用,并且同时包含RectangleTriangle的标头,那么最终会得到一个包含两次Point标头的翻译单元。

在头中定义函数时,需要向编译器指示它不应使其成为全局可见的定义。正常的方法是使用inline,这也向编译器表明,如果有意义的话,它应该尽量不调用函数。使用inline的另一种选择是使函数成为static,但在这种情况下,您实际上会在最终可执行文件中获得该函数的多个副本:尽管编译器可能在每个翻译单元中使用该函数的inline版本,但在链接时,会从各处选择并使用一个版本(希望所有其他副本都被丢弃)。差异可以看出,例如,当您的函数中有一个本地static变量时:

inline int f() {
static int rc(0);
return ++rc;
}
static int g() {
static int rc(0);
return ++rc;
}

当您从不同的转换单元调用这些函数f()g()时,后者每个文件都有一个计数器,而前者有一个全局计数器。