Как создать библиотеку только для заголовков?
-
19-09-2019 - |
Вопрос
Я хотел бы упаковать библиотеку, над которой я работаю, как библиотеку только заголовков, чтобы клиентам было проще ее использовать.(Он небольшой, и на самом деле нет смысла помещать его в отдельную единицу перевода). Однако я не могу просто поместить свой код в заголовки, потому что это нарушает правило одного определения 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 :(
}
Другие советы
Используйте защиту заголовков, как предлагает Лиз, и не забудьте поставить «inline» перед методами функции.
т.е.
#ifndef MY_HEADER_H_
#define MY_HEADER_H_
inline RetType FunctionName( ParamType1 param1, ParamType2 param2 )
{
// Function body
return retType;
}
#endif
Кроме того, я думаю, вам нужно избегать любого использования глобальных переменных или статических переменных в коде библиотеки только для заголовков.
Используйте защиту заголовков для частей, которые компилируются в одном месте.