На данный вопрос уже ответили:
Уважаемые коллеги, есть у меня основной файл - "test.cpp":
#include "pch.h"
#include <common.h>
#include "String.h" // Здесь определяется мой класс строки
int main()
{
double d = 12.536;
double r = common::round(d);
return 0x0000;
}
Файл "common.h" - это мой собственный заголовочный файл:
#pragma once
#ifndef COMMON_h
#define COMMON_h
namespace common
{
double round(double val, unsigned precision = 0);
}
#endif
Этот файл лежит где-то на диске D:\, и в компиляторе я в свойствах проектах добавил директорию поиска включаемых файлов. Он его прекрасно находит, но при сборке приложения выдаёт ошибку LNK2019. Рядом с этим файлом в той же директории лежит "common.cpp":
#pragma once
#include <common.h>
double common::round(double val, int precision)
{
/// Тут какой-то код
return 0.0;
}
Если я помещаю реализацию метода round() внутрь файла "common.h", то всё работает нормально, но только если я единожды подключаю этот файл. А вот если я его включу и в основной "test.cpp" и в "String.h", то уже выкидывает ошибку LNK2005. Подскажите, пожалуйста, как мне решить эту проблему. Заранее спасибо :)
Теоретическая часть.
Когда компилятор находит определение функции, то он добавляет код функции в объектный файл и экспортирует её имя. Если определить функцию в заголовочном файле, то этот заголовочный файл включается в текст *.cpp файла и будет создан объектный файл с экспортируемой функцией. Если несколько файлов включат этот заголовочный файл себе, то получится, что в нескольких объектных файлах окажутся функции с одинаковыми именами. При линковке объектных файлов линковщик не сможет выбрать нужную функцию, т.к. их будет несколько с одинаковыми именами.
Практическая часть: есть файлы main.cpp, common.h и common.cpp.
Пример 1: функция round()
в объявлена в common.h и определена в common.cpp
Лучший вариант. Функция будет создана только в объектном файле common.obj. При линковке вместе main.obj и common.obj будет только одна функция. Всё ОК!
Пример 2: функция round()
определена в common.h.
Плохой вариант. Этот заголовочный файл включат main.cpp и common.cpp. Получатся два объектных файла main.obj и common.obj, которые будут иметь в себе определение функции round()
. При линковке вместе этих объектных файлов будет ошибка линковки, т.к. линковщик увидит две функции с одинаковыми именами.
Решения:
inline
. Inline функции не являются так таковыми функциями. Компилятор на месте их вызова вставляет тело функции.Если пишите реализацию в заголовочном файле, то объявляйте функцию как inline
. Тогда наличие реализации этой функции в каждой единице трансляции не будет ошибкой, линкер возьмет любую из реализаций (которые должны быть одинаковы):
namespace common
{
inline double round(double val, unsigned precision = 0)
{
…
}
}
Где лежит ваш common.cpp
- "рядом" или "не рядом" - не имеет никакого значения. Вы должны сами явно добавить ваш common.cpp
файл в ваш проект, чтобы он компилировался и линковался вместе со всеми остальными файлами программы, т.е. вместе с test.cpp
.
Вы этого, очевидно, не сделали. Пока вы этого не сделаете - будет ошибка линковки LNK2019.
Либо так, либо избавляйтесь от common.cpp
вообще и реализуйте вашу функцию в common.h
как inline
.
не могу понять , в чём ошибка , пытаюсь просто для начала вывести id из БД oracle
При попытке подключения к imap mailru выплевывает ошибку CURLE_LOGIN_DENIED, пробовал различные комбинации логина (с хостом и без) тот же результат, есть...
При клике на другую запись в гриде и имеющихся не сохраненных данных в предыдущей строке бросается предупреждение: перейти без сохранения...