Извините, если это дубликат, но те, которые я нашел … ну, я подумал, что попробовал то же самое решение, но безрезультатно. Во всяком случае, я недавно попытался перенести мою реализацию моих обычно используемых случайных функций в один заголовочный файл: я знаю, как работают функции, сомневаюсь, что я изменю их в ближайшее время, и поэтому я решил, что чем меньше файлов, тем лучше (и функции довольно короткие).
Итак, я попробовал это. Вставьте содержимое файла .cpp в новый файл и добавьте охрану. Тогда просто включите это и вуаля, это работает. К сожалению, я включил его дважды и обнаружил, что раздаю копии одной и той же функции по каждому файлу, таким образом, возникает ошибка. (все еще немного запутываешься, почему это происходит с защитой заголовков, так как у тебя все равно получается одна копия, но я думаю, что так и есть). Во всяком случае, я погуглил (и SO), и обнаружил, что если вы объявите их как встроенные — что имеет смысл в этой ситуации — тогда препроцессор (или это также компоновщик?) Сделает это правильно. Теперь, когда я думаю об этом … как маленький вопрос, DEFINES являются локальными для файла или глобальными по объему? (то есть, если я включу заголовок в два файла с защитой заголовка, которая определяет … включают ли оба файла его, так как определения встречаются в разных файлах, или только один раз? Если бы он был включен дважды, вы бы получили несколько объявлений (но не определяет) ту же функцию / класс / структуру, которая, как я думал, выдает ошибку, но я полагаю, что это не происходит в разных файлах? В противном случае, возможно, она не будет включена и не будет знать, что это такое. повторно спросите, DEFINES локально для файла?)
Вот что у меня есть в файле, чьи функции дублируются (мысль, содержащая только одну функцию)
#ifndef RANDOM_H
#define RANDOM_H
//needed for getting system time and for random generation functions rand and srand
#include <time.h>
#include <stdlib.h>
//this function returns a random number between an inclusive range
inline int randomRange(const int & min, const int & max)
{
if (max >= min)
return ((rand() % (max+1-min))+min);
else
return ((rand() % (min+1-max))+max);
}
#endif
Тогда у меня просто есть #include в двух файлах, в этом файле (это «random.h»)
Что мне не хватает?
РЕДАКТИРОВАТЬ: Сообщение об ошибке было:
множественное определение `randomRange (int const&Int const&) ‘|
Во время небольшого перерыва я закрыл IDE. После повторного открытия все было исправлено. Очевидно, что добавление встроенного DID исправляет это, но, в отличие от файлов cpp при запуске, заголовочные файлы (если они не добавлены в проект) не обновляются, если вы не сохраните их вручную. После сохранения все заработало. Извините, все.
Урок дня: исправляя такие ошибки, убедитесь, что ваши файлы обновлены …
Определения макросов являются локальными для модуля перевода: при компиляции исходного файла препроцессор расширяет различные директивы препроцессора (#define
, #include
и т. д.) и передает результат фактическому компилятору. Это делается один раз для каждого файла, а не один раз. Причиной включения защиты является то, что вполне вероятно, что один и тот же заголовок будет дважды включен в одну и ту же единицу перевода. Например, если у вас есть тип, скажем, Point
, который используется классами Rectangle
а также Triangle
и вы включаете оба заголовка для Rectangle
а также Triangle
, вы в конечном итоге с блоком перевода, включая заголовок для Point
дважды.
Когда вы определяете функцию в заголовке, вам нужно указать компилятору, что она не должна делать ее глобально видимым определением. Нормальный способ заключается в использовании inline
для этого, что также указывает компилятору, что он должен стараться не вызывать функцию, если это имеет смысл. Альтернатива использованию inline
это сделать функцию static
но в этом случае вы на самом деле получите несколько копий функции в вашем конечном исполняемом файле: даже если компилятор может использовать inline
версия функции в каждой единице перевода, во время ссылки выбирается и используется везде (и, надеюсь, все остальные копии будут отброшены). Разницу можно увидеть, например, когда у вас есть местный static
переменная в вашей функции:
inline int f() {
static int rc(0);
return ++rc;
}
static int g() {
static int rc(0);
return ++rc;
}
Когда вы вызываете эти функции f()
а также g()
из разных единиц перевода последний будет иметь счетчик на файл, а первый — глобальный счетчик.
Других решений пока нет …