好的,到目前为止,我认为头文件中定义的函数被视为内联函数,就像模板内容一样,定义一次,以及所有这些。
我也使用包含保护,但我仍然有多个已定义对象的链接器错误,我知道这是因为所有这些不同的单元重复了东西,链接器试图找出哪个项目是正确的。
我也知道内联只是一个建议,甚至可能不被编译器等使用。
然而,我必须在我编写的那个小标题工具集中明确定义所有这些小函数。
即使函数很大,我也必须将它们声明为内联,编译器仍然可能会忽略该提示。
然而,无论如何我必须对它们进行定义。
示例:
#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中的内联内容,对吧?
我只是对这里的原因感到好奇,希望它不是重复的,谢谢你的时间。
答案 0 :(得分:4)
包含保护仅防止在相同翻译单元中包含两次的代码。因此,如果您有多个包含相同标头的文件,则会多次包含该代码。默认情况下,标头中定义的函数不是内联的,因此这将为您提供链接器错误 - 您需要使用inline关键字定义这些函数,除非它们是类的成员函数。
另请注意,包含双下划线的名称是为C ++实现而保留的 - 您不能在自己的代码中创建此类名称。
答案 1 :(得分:1)
会员功能可能会内联 - 您无法强制内联! - 如果(a)它们是在类中定义的,或者如果(b)你在定义中使用inline-clause。请注意,如果您使用的是inline子句,则不应在标题中定义函数 - 唯一的例外是模板,因为它们是“特殊的”。
刚刚更新了问题:
此标题的每个用户都将具有函数的定义 - >多重定义。你需要分开定义和声明!
答案 2 :(得分:1)
关于一个定义规则的全部内容。这表明在C ++程序中,您只能为链接到的所有翻译单元中的每个非内联函数(以及各种其他类型的实体)定义一个定义。
标记函数inline
可以启用通常的一个定义规则的例外。它声明(释义)每个翻译单元可以有一个内联函数的定义,前提是所有定义都匹配,并且在使用内联函数的每个翻译中提供定义。
包含警卫可以防止您通过多次包含包含定义的头文件,意外地为每个翻译单元提供多个定义。
要满足非内联函数的一个定义规则,您仍需要确保只有一个包含函数定义的转换单元。通常的方法是仅在头文件中声明函数并使用包含定义的单个源文件。