2015-09-15 54 views
6

mam podobny scenariusz jak określono poniżej:Jak uniknąć konfliktów zmiennej/funkcja z dwóch bibliotek w C++

Mam jeden plik header first.h Posiada funkcję:

char* getName(); 

i powiązany plik cpp first.cpp konieczności definicja

char* getName(){return "first";} 

funkcja i drugi plik header second.h to ma Funkcja:

char* getName(); 

skojarzony plik cpp second.cpp konieczności definicja funkcji

char* getName(){return "second";} 

Teraz jest main() funkcja:

#include "first.h" 
#include "second.h" 

int main(){ 
return 0; 
} 

kiedy obejmują te .h plików, kompilator daje błąd Pod funkcja getName(), ponieważ jest w konflikcie.

Jak pozbyć się tego problemu, bez zmiany .h files

+0

Czy funkcje są wbudowane, czy prawdziwe nagłówki zawierają tylko deklaracje? To dlatego nigdy nie rozumiem, dlaczego C nie ma przestrzeni nazw. Bez szablonów i przeciążania nie ma nic skomplikowanego i rozwiążą wszystkie konflikty nazewnictwa i przestaną używać przestarzałych prefiksów. – Jens

+0

Czy to jest 'C' lub' C++ '? Dla C++ skorzystaj z tego samouczka: http://www.tutorialspoint.com/cplusplus/cpp_namespaces.htm –

+0

nie możesz pozbyć się tej sytuacji bez zmiany tych plików nagłówkowych w c. Jeśli zmienisz jedną z metod w plikach nagłówkowych jako statyczną, będzie kompilować lub używać przestrzeni nazw w języku C++ dla tych metod. jeśli chcesz użyć jednego z plików nagłówkowych i nie chcesz zmieniać nagłówków, użyj #ifndef structure do włączenia jednego z plików nagłówkowych. –

Odpowiedz

5

Można używać nazw przy tym te pliki nagłówka:

w pliku cpp:

namespace first 
{ 
    #include "first.h" 
} 

namespace second 
{ 
    #include "second.h" 
} 

Następnie można użyć funkcji tak:

... 
first::getName(); 
second::getName(); 
... 

Edytuj: Dzięki komentarzowi Jensa działa to tylko wtedy, gdy funkcje są wbudowane. Jeżeli funkcje nie są inline i naprawdę nie można zmienić pliki nagłówkowe można tworzyć „Otulina” pliki nagłówkowe do tych funkcji:

pliku wrapper-first.h:

namespace first 
{ 
    char* getName(); 
} 

pliku wrapper-pierwszy .cpp:

#include "wrapper-first.h" 
#include "first.h" 

char* first::getName() 
{ 
    return ::getName(); 
} 

... i utworzyć to samo dla drugiego pliku nagłówkowego. Następnie dołącz pliki wrpper-include do pliku cpp i użyj kodu jak wyżej.

+1

Działa to tylko wtedy, gdy funkcje są funkcjami wbudowanymi. Jeśli nagłówki po prostu deklarują funkcje i implementacja jest połączona, to nie zadziała. – Jens

+0

@Jens To zdarza się również w nienazwanych obszarach nazw? (Nie wiem, tylko pytam). –

+0

Zrobiłem to, ciągle ten sam błąd. –

3

To będzie trudne. Obie biblioteki będą zawierały symbol getName. Łącznik rozwiąże symbol getName przy użyciu pierwszej biblioteki, która go zapewnia. Zdarza się to niezależnie od tego, co robisz z nagłówkami, niezależnie od tego, czy jest to. Po prostu masz szczęście, że kompilator już narzekał i dał ci wyraźny błąd.

Pomysł Thomasa Bardera ukryje problem z kompilatorem. To nie będzie naprawić problem linkera. first::getName nadal będzie używać ::getName z biblioteki sekund lub odwrotnie.

Niezbędnym rozwiązaniem jest posiadanie first::getName w swojej bibliotece z własną biblioteką. Ta biblioteka powinna łączyć się tylko z pierwszą biblioteką. Główny plik wykonywalny łączy się z biblioteką pomocniczą i oryginalną drugą biblioteką. Łącznik nie ma już duplikatów symboli, ponieważ jest wywoływany dwukrotnie. Podczas budowania biblioteki pomocniczej, ::getName pochodzi jednoznacznie od pierwszej biblioteki. Podczas budowania głównego pliku wykonywalnego jednoznacznie pochodzi z drugiej biblioteki.