2015-04-29 8 views
7

(Mac)C++ doppelte Symbole

Ich habe versucht, Namespaces, sind Wachen, Pragma einmal usw.

Grundsätzlich ist dies die Struktur:

CMakeLists.txt

add_executable(Game Game/main.cpp Game/rtexture.cpp) 

Spiel/main.cpp

#include "cleanup.h" 

//... 
cleanup(foobar); 

Spiel/rtexture.cpp

#include "cleanup.h" 

//... 
cleanup(foobar); 

cleanup.h

//various includes 

template<typename T, typename... Args> 
void cleanup(T *t, Args&&... args){ 
    //Cleanup the first item in the list 
    cleanup(t); 
    //Recurse to clean up the remaining arguments 
    cleanup(std::forward<Args>(args)...); 
} 
/* 
* These specializations serve to free the passed argument and also provide the 
* base cases for the recursive call above, eg. when args is only a single item 
* one of the specializations below will be called by 
* Cleanup(std::forward<Args>(args)...), ending the recursion 
* We also make it safe to pass nullptrs to handle situations where we 
* don't want to bother finding out which values failed to load (and thus are null) 
* but rather just want to clean everything up and let cleanup sort it out 
*/ 
template<> 
void cleanup<SDL_Window>(SDL_Window *win){ 
    if (!win){ 
     return; 
    } 
    SDL_DestroyWindow(win); 
} 
template<> 
void cleanup<SDL_Renderer>(SDL_Renderer *ren){ 
    if (!ren){ 
     return; 
    } 
    SDL_DestroyRenderer(ren); 
} 
template<> 
void cleanup<SDL_Texture>(SDL_Texture *tex){ 
    if (!tex){ 
     return; 
    } 
    SDL_DestroyTexture(tex); 
} 
template<> 
void cleanup<SDL_Surface>(SDL_Surface *surf){ 
    if (!surf){ 
     return; 
    } 
    SDL_FreeSurface(surf); 
} 

Wenn jemand fragt, nahm ich diesen "cleanup.h" aus einem Tutorial kann aber nicht einen Weg finden, es ist in mehrere Klassen ohne doppelte Symbole zu deklarieren.

Home at cruz45488-y19-MBA13-12 in ~/desktop/sdlworkspace/tmp 
$ make 
Linking CXX executable Game 
duplicate symbol __ZN5RUtil7cleanupI10SDL_WindowJEEEvPT_DpOT0_ in: 
    CMakeFiles/Game.dir/Game/main.cpp.o 
    CMakeFiles/Game.dir/Game/rtexture.cpp.o 
duplicate symbol __ZN5RUtil7cleanupI12SDL_RendererJEEEvPT_DpOT0_ in: 
    CMakeFiles/Game.dir/Game/main.cpp.o 
    CMakeFiles/Game.dir/Game/rtexture.cpp.o 
duplicate symbol __ZN5RUtil7cleanupI11SDL_TextureJEEEvPT_DpOT0_ in: 
    CMakeFiles/Game.dir/Game/main.cpp.o 
    CMakeFiles/Game.dir/Game/rtexture.cpp.o 
duplicate symbol __ZN5RUtil7cleanupI11SDL_SurfaceJEEEvPT_DpOT0_ in: 
    CMakeFiles/Game.dir/Game/main.cpp.o 
    CMakeFiles/Game.dir/Game/rtexture.cpp.o 

Irgendwelche Hilfe? Vielen Dank.

+0

Sind Sie mit '#ifndef CLEANUP_H #define CLEANUP_H # endif' in cleanup.h? Wenn nicht, dann musst du es benutzen. – Jahid

+0

Nein, ich benutze es - Entschuldigung für die späte Antwort. Wie in den folgenden Antworten funktioniert 'inline void' aber trotzdem danke. –

Antwort

10

Explizite Funktionsvorlagenspezialisierungen unterliegen der Regel für eine Definition, genau wie reguläre Funktionen. Fügen Sie inline hinzu, um Definitionen in einem Header zuzulassen; oder definieren Sie sie in einer Quelldatei mit Deklarationen in der Kopfzeile.

5

Ich sehe keine Wächter. Weil Sie diese Kopfzeile in mehrere Dateien einfügen, ist #ifdef nicht enugh - Sie müssen das Schlüsselwort inline verwenden, das dem Linker sagt, dass diese bestimmte Funktion in mehr als einer Übersetzungseinheit definiert sein kann.

#ifndef CLEANUP_H 
#define CLEANUP_H 

//includes... 

template<> 
inline void cleanup<SDL_Window>(SDL_Window *win){ 
    if (!win){ 
     return; 
    } 
    SDL_DestroyWindow(win); 
} 
template<> 
inline void cleanup<SDL_Renderer>(SDL_Renderer *ren){ 
    if (!ren){ 
     return; 
    } 
    SDL_DestroyRenderer(ren); 
} 
template<> 
inline void cleanup<SDL_Texture>(SDL_Texture *tex){ 
    if (!tex){ 
     return; 
    } 
    SDL_DestroyTexture(tex); 
} 
template<> 
inline void cleanup<SDL_Surface>(SDL_Surface *surf){ 
    if (!surf){ 
     return; 
    } 
    SDL_FreeSurface(surf); 
} 

#endif /* CLEANUP_H */ 
Verwandte Themen