Как я вижу, если код в файле основан на других вещах, которые должны быть объявлены, он должен включать файл, содержащий эти объявления. В противном случае, материал становится хрупким и включает в себя все время и в определенном порядке, и все становится безобразным. Так что для меня «дубликаты включают» - хорошая вещь; каждый фрагмент кода может позаботиться о своих собственных зависимостях с меньшими хлопотами.
Что касается того, как не допустить взлома дубликатов включенных ... есть идиома под названием "включить охрану". Они выглядят примерно так ...
(file1.h)
#ifndef FILE1_H
#define FILE1_H
(the meat of file1.h goes in here)
#endif
Когда этот файл включается в первый раз, FILE1_H
еще не определен (или не должен быть, если вы выберете более подходящие имена для своих файлов, чем этот), поэтому код будет включен (и FILE1_H
впоследствии определяется). Однако в следующий раз, когда он будет включен, FILE1_H
теперь определен, поэтому код пропускается.
(Кстати, для этого подойдет любое имя макроса, если оно уникально для каждого файла. Но именно это ограничение является основной причиной, по которой имя макроса почти всегда основано на имени файла.)
На большинстве компиляторов #pragma once
также работает. Но это не стандартно; если вы хотите использовать любой компилятор, какой захотите, не используйте его (и не используйте в дополнение к включенному охраннику).