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

时间:2012-10-06 17:34:53

标签: c++ header inline multiple-definition-error

对不起,如果这是重复的,但是我找到了......好吧,我以为我尝试了同样的解决方案,但无济于事。无论如何,我最近尝试将我常用的随机函数的实现转移到单个头文件:我知道函数是如何工作的,怀疑我会很快改变它们,所以我想,更少的文件更好(和功能很短)。

所以,我试过了。将.cpp文件的内容保存到新文件中,并添加了防护。然后只是包括它,瞧,它的工作原理。不幸的是,我把它包括了两次,并发现,我正在向每个文件分发相同功能的副本,因此错误。 (仍然有点混淆为什么这是与标题警卫,因为你最终得到一个副本,但我想它确实)。无论如何,我用google搜索(和SO'ed),并发现如果你将它们声明为内联 - 这在这种情况下是有意义的 - 那么预处理器(或者也就是链接器?)会做得对。现在我想到了......作为一个小问题,文件是本地的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

然后我在这个文件(即“random.h”)

中的两个文件中只有#includes

我错过了什么?

编辑:错误消息是:

`randomRange的多重定义(int const&amp;,int const&amp;)'|

虽然稍作休息,但我关闭了IDE。重新开放后,一切都得到了修复。显然,添加内联DID修复它,但是,与运行时的cpp文件不同,头文件(如果没有添加到项目中)不会更新,除非您手动保存它们。保存后,它工作。对不起,大家。

每日课程:修复此类错误时,请确保您的文件已更新...

1 个答案:

答案 0 :(得分:0)

宏定义是转换单元的本地定义:在编译源文件时,预处理器会扩展各种预处理程序指令(#define#include等)并将结果传递给实际的编译器。对于每个文件,这不仅仅执行一次。包含警卫的原因是很可能在同一翻译单元中包含两次相同的标题。例如,如果您有类型{,1}},类PointRectangle使用的类型,则包含TriangleRectangle的标题,您最终会得到一个翻译单元,其中包括Triangle两次的标题。

在标头中定义函数时,需要向编译器指明它不应使其成为全局可见的定义。通常的方法是使用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()时,后者每个文件都有一个计数器,而前者有一个全局计数器。