Принцип прост. В .h можно ставить только то, что не производит кода. Как только в проекте появится второй CPP и задействует этот хедер, код будет произведён дважды, и компоновщик (cl/ld/ilink) будет ругаться, что переменная или функция в двух экземплярах. Что именно не производит кода…
• Определения макросов. Они в принципе кода не производят.
• Объявление любого типа. Оно лишь говорит об устройстве этого самого типа; код же производят те, кто этим типом пользуются.
• Шаблоны. Код производит не сам шаблон, а факт расшаблонивания. Разумеется, шаблон может расшаблониться в двух единицах компиляции, но с этим автоматически бороться научились.
• inline— код производит не сам inline, а факт включения. inline бывает как явный ключевым словом, так и неявный — в теле класса.
• Прототипы и extern — они говорят: код есть, но где-то не здесь.
• Constexpr C++11. Они подставляют значение.
• Некоторые const в зависимости от компилятора. Например, на Borland const double производит код, а const int — нет.
Производят код и в хедерах запрещены.
• Переменная без extern, даже const.
• Функция, которая не inline.
• Полностью специализированный шаблон, в котором не осталось шаблонных параметров (template<>
).
Не производят кода, но и лучше закинуть в CPP.
• Некоторые скрытые (private) inline и шаблоны, если они не используются из хедера.