49

我想将我正在开发的库打包为仅标头库,以使客户更容易使用。(它很小,真的没有理由把它放到一个单独的翻译单元中)但是,我不能简单地将我的代码放在标题中,因为这违反了 C++ 的单一定义规则。(假设库头包含在一个客户项目的多个翻译单元中)

如何修改库以使其仅包含标题?

4

4 回答 4

77

您可以使用以下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 :(
}
于 2010-02-08T22:41:31.370 回答
10

按照 Liz 的建议使用标头保护,不要忘记在函数方法之前放置“内联”。

IE

#ifndef MY_HEADER_H_
#define MY_HEADER_H_

inline RetType FunctionName( ParamType1 param1, ParamType2 param2 )
{
    // Function body
    return retType;
}

#endif
于 2010-02-08T22:41:48.217 回答
5

此外,我认为您需要避免在仅标头库代码中使用任何全局变量或静态变量。

于 2010-02-08T22:41:59.673 回答
-2

对在一个地方编译的部分使用标头保护。

于 2010-02-08T22:40:42.587 回答