为什么我必须在这里明确声明函数内联?

时间:2011-05-01 09:47:50

标签: c++ inline linker-errors

好的,到目前为止,我认为头文件中定义的函数被视为内联函数,就像模板内容一样,定义一次,以及所有这些。

我也使用包含保护,但我仍然有多个已定义对象的链接器错误,我知道这是因为所有这些不同的单元重复了东西,链接器试图找出哪个项目是正确的。

我也知道内联只是一个建议,甚至可能不被编译器等使用。

然而,我必须在我编写的那个小标题工具集中明确定义所有这些小函数。

即使函数很大,我也必须将它们声明为内联,编译器仍然可能会忽略该提示。

然而,无论如何我必须对它们进行定义。

示例:

#ifndef texture_math_h__
#define texture_math_h__

float TexcoordToPixel(float coord, float dimension)
{
    return coord * dimension;
}

float PixelToTexcoord(float pixel, float dimension)
{
    return pixel / dimension;
}

float RecalcTexcoord(float coord,float oldDimension, float newDimension)
{
    return PixelToTexcoord(TexcoordToPixel(coord,oldDimension),newDimension);
}
#endif // texture_math_h__

错误是,已经在xxx.obj中为包含文件的每个单元定义了blabla

当我声明所有这些内联时,它正确链接。

这是什么原因?这不是一个大问题,哎呀,优化也可能是cpp中的内联内容,对吧?

我只是对这里的原因感到好奇,希望它不是重复的,谢谢你的时间。

3 个答案:

答案 0 :(得分:4)

包含保护仅防止在相同翻译单元中包含两次的代码。因此,如果您有多个包含相同标头的文件,则会多次包含该代码。默认情况下,标头中定义的函数不是内联的,因此这将为您提供链接器错误 - 您需要使用inline关键字定义这些函数,除非它们是类的成员函数。

另请注意,包含双下划线的名称是为C ++实现而保留的 - 您不能在自己的代码中创建此类名称。

答案 1 :(得分:1)

会员功能可能会内联 - 您无法强制内联! - 如果(a)它们是在类中定义的,或者如果(b)你在定义中使用inline-clause。请注意,如果您使用的是inline子句,则不应在标题中定义函数 - 唯一的例外是模板,因为它们是“特殊的”。
刚刚更新了问题:
此标题的每个用户都将具有函数的定义 - >多重定义。你需要分开定义和声明!

答案 2 :(得分:1)

关于一个定义规则的全部内容。这表明在C ++程序中,您只能为链接到的所有翻译单元中的每个非内联函数(以及各种其他类型的实体)定义一个定义。

标记函数inline可以启用通常的一个定义规则的例外。它声明(释义)每个翻译单元可以有一个内联函数的定义,前提是所有定义都匹配,并且在使用内联函数的每个翻译中提供定义。

包含警卫可以防止您通过多次包含包含定义的头文件,意外地为每个翻译单元提供多个定义。

要满足非内联函数的一个定义规则,您仍需要确保只有一个包含函数定义的转换单元。通常的方法是仅在头文件中声明函数并使用包含定义的单个源文件。