Каждый файл .cpp
и все файлы, включенные в файл .cpp
, называются единицей перевода . Компилятор компилирует каждую единицу перевода отдельно. Затем компоновщик объединяет все это в один исполняемый файл.
Прежде чем компилятор фактически скомпилирует код, он сначала выполняет все операторы предварительной обработки, например, операторы #include
в обоих ваших .cpp
файлах. Оператор #include
просто берет содержимое указанного файла и «копирует» его в файл, где находится оператор #include
. Например, fun.cpp
может выглядеть следующим образом после предварительной обработки:
/* the contents of the iostream file goes here */
using namespace std;
void sum()
{
cout << "hello";
}
Для Main.cpp
, что-то вроде этого:
/* the contents of the cstdlib file goes here */
/* the contents of the iostream file goes here */
using namespace std;
void sum()
{
cout << "hello";
}
int main(int argc, char** argv)
{
sum();
return 0;
}
Как видите, содержимое fun.cpp
было "вставлено" в Main.cpp
. Итак, теперь у вас есть два определения sum()
, что является нарушением правила единого определения (ODR) в C ++. Поскольку компилятор обрабатывает каждую единицу перевода отдельно, эта ошибка не была обнаружена, пока компоновщик не обнаружил, что у вас есть два разных определения, и в результате справедливо пожаловался.
Поскольку функция sum()
довольно проста, один из способов решения этой проблемы - сделать функцию sum()
inline
, переименовать файл fun.cpp
в fun.h
и включить fun.h
в * 1030. * вместо fun.cpp
.
// fun.h
#include <iostream>
inline void sum()
{
std::cout << "hello";
}
// main.cpp
#include <cstdlib>
#include <iostream>
#include "fun.h" // Note "fun.h"
int main(int argc, char** argv)
{
sum();
return 0;
}
Для больших функций или если вы хотите скрыть реализацию, ответ Als более уместен.