Как избежать конфликтов переменных / функций из двух библиотек в 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 однозначно приходит из первой библиотеки. При построении основного исполняемого файла он однозначно из второй библиотеки.