Предотвращает ли #ifndef определение функции дважды при связывании двух объектных файлов?

У меня есть две реализации класса (.cpp files)

Им обоим нужна функция, которая была реализована в header(.h) файл. Оба файла .cpp включают в себя файл .h. После компиляции два .cpp файлов становится два .o файлы.

Функция должна быть определена дважды при связывании двух объектных файлов?

Можно #ifndef предотвратить эту ситуацию?

я использовал #ifndef но я получил следующее сообщение,

ld: 1 duplicate symbol for architecture x86_64

2

Решение

Вы должны понимать разницу между функцией декларация (утверждение, что функция с заданным именем и сигнатурой существует) и функция определение (код, который определяет, что на самом деле делает функция).

если ты определять функция в заголовке, затем функция будет определена в каждом объектном файле, и вы получите конфликт при попытке связать их вместе; #ifndef не решит эту проблему.

Там не будет такой проблемы, если вы объявлять функция в заголовке, и определять это в исходном файле (который должен быть скомпилирован в объект и связан с объектами, которые его используют). В этом простом случае #ifndef не нужен

Например, функция foo может быть объявлено в foo.h:

int foo(int);

и определяется в foo.cpp:

int foo(int n)
{
return(n+3);
}

#ifndef макрос решает другую проблему.

5

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

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

// Foo.h

int foo(){return 1;}

// UsesFoo1.cpp

#include "Foo.h"int usesFoo2(){return foo();}

// UsesFoo2.cpp

#include "Foo.h"int usesFoo1(){return foo();}

// Main.cpp

#include <iostream>
int usesFoo1();
int usesFoo2();

int main()
{
std::cout << usesFoo1() + usesFoo2() << std::endl;
}

Это приводит к ошибке компоновщика, потому что int foo() определяется в двух отдельных единицах перевода. Однако при добавлении inline ключевое слово здесь:

// Foo.h

inline int foo(){return 1;}

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

2

По вопросам рекламы [email protected]