Как избежать конфликтов переменных / функций из двух библиотек в C++
у меня есть аналогичный сценарий, как описано ниже:
у меня есть один заголовочный файл first.h
Он имеет функцию:
char* getName();
и связанный файл cpp first.cpp
получив определение функции
char* getName(){return "first";}
и второй заголовочный файл второй.ч он имеет функцию:
char* getName();
связанный файл cpp second.cpp
получив определение функции
char* getName(){return "second";}
теперь есть :
#include "first.h"
#include "second.h"
int main(){
return 0;
}
когда я включаю те .h
файлы, компилятор дают ошибку при функции getName()
как это противоречит.
Как избавиться от этой проблемы без изменения .h files
2 ответов
вы можете использовать пространства имен при включении этих заголовочных файлов:
в вашем cpp-файле:
namespace first
{
#include "first.h"
}
namespace second
{
#include "second.h"
}
затем вы можете использовать следующие функции:
...
first::getName();
second::getName();
...
Edit: благодаря комментарию Йенса это работает только в том случае, если функции встроены. Если функции не встроены, и вы действительно не можете изменить файлы заголовков, вы можете создать файлы заголовков "wrapper" для этих функций:
сначала обертка.h:namespace first
{
char* getName();
}
фантик-первый файл.cpp:
#include "wrapper-first.h"
#include "first.h"
char* first::getName()
{
return ::getName();
}
...и создайте то же самое для второго файла заголовка. Затем вы просто включаете файлы wrpper-include в свой cpp-файл и используете код, как указано выше.
это будет сложно. и библиотеки будут содержать getName
символ. Компоновщик разрешит getName
символ, используя первую библиотеку, предоставляющую его. Это происходит независимо от что вы делаете с заголовками. Вам просто повезло, что компилятор уже пожаловался и дал вам явную ошибку.
идея Томаса Бардера скроет проблему компилятора. Это не Исправлена ошибка линкера. first::getName
по-прежнему будут использовать ::getName
от второй библиотека, или наоборот.
необходимым решением является наличие first::getName
в своем собственные библиотека. Эта библиотека должна линковать только первая библиотека. Основные исполняемые ссылки на вспомогательную библиотеку и исходную вторую библиотеку. Компоновщик больше не имеет повторяющихся символов, потому что он вызывается дважды. При создании вспомогательной библиотеки,::getName
однозначно приходит из первой библиотеки. При построении основного исполняемого файла он однозначно из второй библиотеки.