Итак, кто-то пришел ко мне с проектом, который не удалось связать с ошибкой LNK2005: символ, уже определенный в объекте (с использованием Visual Studio 2010). В этом случае я знаю , что является неправильным (и, следовательно, может указывать их на правильное решение), но я не знаю , почему это неправильно на уровне, чтобы дать хорошее объяснение этому (чтобы это не происходило еще раз).Как объяснить этот LNK2005?
// something.h
#ifndef _SOMETHING_H
#define _SOMETHING_H
int myCoolFunction();
int myAwesomeFunction() // Note implementing function in header
{
return 3;
}
#endif
-
// something.cpp
#include "something.h"
int myCoolFunction()
{
return 4;
}
-
// main.cpp
#include <iostream>
#include "something.h"
int main()
{
std::cout << myAwesomeFunction() << std::endl;
}
Это не удается соединение, и фиксируется ввод myAwesomeFunction() в .cpp и оставив заявление в .h.
Мое понимание того, как работает компоновщик, в значительной степени зависит от here. Насколько я понимаю, мы предоставляем символ, который требуется в одном месте.
Я искал MSDN article on LNK2005, который соответствует тому, как я ожидаю, что линкеры будут вести себя (предоставить символ более одного раза -> линкер запутался), но, похоже, не охватывает этот случай (что означает, что я не понимаю что-то очевидно о связи).
вопросы доходности Google и StackOverflow с людьми, не включающими в себя #ifndef
или #pragma once
(что приводит к множественным декларациям, предусмотренные символов)
A related question I found on this site имеет ту же проблему, но ответ не объясняет, почему мы адекватно оценивая эту проблему с моим уровнем понимания.
У меня есть проблема, я знаю решение, но я не знаю, почему мое решение работает
Возможно, было бы разумнее, если вы запустите все ваши .cpp-файлы через препроцессор, а затем подсчитайте, сколько экземпляров глобального пространства имен «myAwesomeFunction()» есть.Вы знаете, в чем проблема, решение для будущего избежания этой «проблемы» тривиально: «Доктор, мне больно, когда я это делаю». ** «Тогда не делай этого». **. – WhozCraig
Мне нравится знать, почему я что-то делаю, чтобы кто-то сказал: «Эй, зачем ты это делаешь?» У меня лучший ответ, чем «О, кто-то сказал мне». Но да, в повседневной жизни, не злоупотребляя компоновщиком, как правило, я стараюсь избегать. – KidneyChris
Ты и я оба. Компилятор - открытая игра, но я стараюсь уважать компоновщика = P. Это, в конце концов, ближе в девятом иннинге. – WhozCraig