Почему Visual Studio выдает повторяющуюся ошибку, хотя я не включаю явно исходный файл? - PullRequest
0 голосов
/ 30 марта 2020

Я использую Visual Studio 2019. Я создаю новое консольное приложение C ++. У меня есть файл Main. cpp в папке с исходными файлами со следующим кодом:

#include <iostream>

int i = 10;

int main()
{
    std::cout << i << std::endl;
    std::cin.get();
}

Я создаю второй файл в папке с исходными файлами с именем File2. cpp, содержащий только следующую строку:

int i = 2;

Если я пытаюсь скомпилировать этот код, я получаю сообщение об ошибке «найден один или несколько кратно определенных символов». Почему я получаю эту ошибку, хотя я явно не сделал #include "File2.cpp" в Main. cpp?

ОБНОВЛЕНИЕ: ОДНАКО, если я удалю File2. cpp и заменим его вместо этого с файлом в папке Header Files, который называется File2.h (содержит только одну строку: int i = 2), и при прочих равных условиях он компилируется нормально. Как и в предыдущем примере, единственное отличие состоит в том, что вместо второго файла, являющегося исходным файлом. cpp, теперь он является файлом заголовка .h.

Ответы [ 2 ]

4 голосов
/ 30 марта 2020

В C ++ глобальные переменные (объявленные вне любого класса) по умолчанию имеют внешнюю связь. То есть они видны другим модулям, когда приложение связано.

Таким образом, оба файла. cpp предоставляют переменную i для компоновщика, который возражает.

Четыре решения:

1) Поместите одно или оба объявления в другое пространство имен:

namespace Wibble
{
    int i = 2;
}

, чтобы они имели разные полностью квалифицированные имена.

2) Объявите одно или оба как static:

static int i = 2;

, который отключает внешнюю связь.

3) Поместите одно или оба в анонимное пространство имен:

namespace
{
    int i = 2;
}

, которое автоматически назначает уникальное пространство имен каждому - фактически тот же результат, что и (2)

4) Объявить все, кроме одного, как extern без инициализации:

extern int i;

это говорит о том, что переменная i фактически та же самая переменная, что и в другом файле, который не был объявлен как extern.

2 голосов
/ 30 марта 2020

Во-первых, вы никогда не захотите включать файл cpp. Общий способ 1 структурировать ваш код - поместить ваши объявления в один или несколько файлов заголовков, а затем иметь один файл cpp для каждого файла заголовков. Затем вы компилируете и связываете все эти cpp файлы вместе.

Это то, что Visual Studio делает для вас автоматически. Вы создаете все свои заголовочные и cpp файлы в проекте, а затем он скомпилирует каждый из этих cpp файлов и затем свяжет полученные объектные файлы вместе, чтобы создать исполняемый файл. Таким образом, поскольку в Main.cpp и File2.cpp определена одна и та же переменная, вы получите ошибку множественного определения, поскольку оба файла компилируются вместе.

1: , если у вас нет шаблоны

...