我想将我正在开发的库打包为仅标头库,以使客户更容易使用。(它很小,真的没有理由把它放到一个单独的翻译单元中)但是,我不能简单地将我的代码放在标题中,因为这违反了 C++ 的单一定义规则。(假设库头包含在一个客户项目的多个翻译单元中)
如何修改库以使其仅包含标题?
我想将我正在开发的库打包为仅标头库,以使客户更容易使用。(它很小,真的没有理由把它放到一个单独的翻译单元中)但是,我不能简单地将我的代码放在标题中,因为这违反了 C++ 的单一定义规则。(假设库头包含在一个客户项目的多个翻译单元中)
如何修改库以使其仅包含标题?
您可以使用以下inline
关键字:
// header.hpp (included into multiple translation units)
void foo_bad() {} // multiple definitions, one in every translation unit :(
inline void foo_good() {} // ok :)
inline
允许链接器简单地选择一个定义并丢弃其余定义。
(因此,如果这些定义实际上不匹配,您会得到大量未定义的行为......!)
顺便说一句,在类类型中定义的成员函数被隐式标记inline
:
struct myclass
{
void i_am_inline_implicitly()
{
// because my definition is here
}
void but_i_am_not();
void neither_am_i();
};
inline void myclass::but_i_am_not()
{
// but that doesn't mean my definition cannot be explicitly inline
}
void myclass::neither_am_i()
{
// but in this case, no inline for me :(
}
按照 Liz 的建议使用标头保护,不要忘记在函数方法之前放置“内联”。
IE
#ifndef MY_HEADER_H_
#define MY_HEADER_H_
inline RetType FunctionName( ParamType1 param1, ParamType2 param2 )
{
// Function body
return retType;
}
#endif
此外,我认为您需要避免在仅标头库代码中使用任何全局变量或静态变量。
对在一个地方编译的部分使用标头保护。