Несколько файлов C ++ приводят к «множественному определению» ошибка?

Я впервые использую несколько файлов C ++ в одном проекте. Оба должны включать защищенный (#ifndef) заголовочный файл. Однако, когда я это делаю, я получаю многократную ошибку определения.

У меня есть два файла .cpp, который напрямую вызывает заголовок, и один косвенно (другой включает его), а затем два других заголовочных файла, которые его включают.

Так что мне нужно сделать, чтобы избавиться от ошибки?

ОШИБКА:

obj \ Debug \ main.o || В функции Z14sortLibQtyTest4BookS_':|
[PATH]\miscFuncs.h|16|multiple definition of
sortLibQtyTest (Книга, Книга) ‘

КОД:

bool sortLibQtyTest(Book a, Book b){ return a.getQty() > b.getQty(); }

Следует отметить, что это не единственная функция, доставляющая мне проблемы, вероятно, более десяти, а некоторые не такие короткие и приятные. Также функции нужны в нескольких файлах.

1

Решение

У вас есть два варианта решения этой проблемы с несколькими определениями: пометьте метод как встроенный или поместите определение в файл .cpp.

1) Отметьте метод встроенным:

// Foo.h

inline bool foo(int i) { return i = 42; }

2) Поместите определение в .cpp файл:

// Foo.h

inline bool foo(int i); // declaration

// Foo.cpp
bool foo(int i) { return i = 42; } // definition

Является ли метод на самом деле встроенным компилятором в первом случае, здесь не имеет значения: inline позволяет определить функцию, не являющуюся членом, в файле заголовка, не нарушая одно правило определения.

2

Другие решения

Суффиксы «.cpp» и «.h» во многом являются условностями. Что касается компилятора, то, откуда взялась строка кода, не имеет значения. Когда вы #include эту функцию в ваши файлы .cpp, вы реализуете эту функцию в этом файле .cpp.

Поэтому, когда компилятор готов и просит компоновщика связать код из ваших двух файлов cpp, он обнаруживает конфликт: две функции с одинаковым именем и отпечатком (аргументы и возврат). Это ошибка

Вам нужно либо:

а. Поместите реализацию в один исходный файл и просто оставьте объявление прототипа в заголовке

// .h
extern bool sortLibQtyTest(Book a, Book b);

// file1.cpp
bool sortLibQtyTest(Book a, Book b) { /* implementation */ }

б. Пометьте функцию как встроенную: когда вы вызываете функцию, компилятор вставляет копии тела функции по мере необходимости, что может быть расточительным, но часто компилятор может определить эффективную работу.

inline bool sortLibQtyTest(Book a, Book b) { return a.getQty() < b.getQty(); }

с. Пометьте функцию как «статическую», которая указывает компилятору создавать копию функции для каждого исходного файла, который ее включает, но не предоставлять ее компоновщику. Если некоторые исходные файлы включают заголовок без использования функции, компилятор должен обнаружить это и удалить его — что не все компиляторы / уровни оптимизации делают, так что это может быть вдвойне расточительным.

static bool sortLibQtyTest(Book a, Book b) {return a.getQty() < b.getQty(); }

д. Избегайте недостатков c, пометьте его статическим

static inline bool sortLibQtyTest(Book a, Book b) { return a.getQty() < b.getQty(); }
2

Если строка, которую вы указали после «CODE», находится в заголовочном файле, вы можете:

  • добавлять inline к определению или
  • удалите тело функции из заголовка и поместите его в 1 (и только 1) ваших исходных файлов.
1
По вопросам рекламы [email protected]