2010-02-08 5 views
27

Ich möchte eine Bibliothek, an der ich gerade arbeite, als Nur-Header-Bibliothek packen, um die Verwendung für die Clients zu vereinfachen. (Es ist klein und es gibt wirklich keinen Grund, es in eine separate Übersetzungseinheit zu setzen). Allerdings kann ich meinen Code nicht einfach in die Kopfzeilen einfügen, da dies gegen die C++ - Definitionsregel verstößt. (Angenommen, der Bibliothekskopf ist in mehreren Übersetzungseinheiten eines Clientprojekts enthalten)Wie erstelle ich eine Nur-Header-Bibliothek?

Wie ändert man eine Bibliothek, um sie nur als Header zu definieren?

Antwort

45

können Sie die inline Schlüsselwort:

// header.hpp (included into multiple translation units) 

void foo_bad() {} // multiple definitions, one in every translation unit :(

inline void foo_good() {} // ok :) 

inline ermöglicht es dem Linker einfach eine Definition wählen und den Rest zu verwerfen.

(Als solcher, wenn diese Definitionen nicht wirklich übereinstimmen, erhalten Sie eine gute Dosis von undefinierten Verhalten ...!)


Als beiseite, Elementfunktionen definiert innerhalb einer Klasse-Typ, implizit inline sind markiert:

struct myclass 
{ 
    void i_am_inline_implicitly() 
    { 
     // because my definition is here 
    } 

    void but_i_am_not(); 
    void neither_am_i(); 
}; 

inline void myclass::but_i_am_not() 
{ 
    // but that doesn't mean my definition cannot be explicitly inline 
} 

void myclass::neither_am_i() 
{ 
    // but in this case, no inline for me :(
} 
+4

+1 von mir. Dies ist so ziemlich alles, was moderne Compiler bedeuten. –

+0

Nitpick: Es erlaubt kein Brechen von ODR; es erlaubt die Funktion mehrfach zu definieren. Die Definitionen müssen noch übereinstimmen. –

+0

@BillyONeal: Ein guter Nitpick. Bearbeitet. – GManNickG

1

Verwenden Sie die Kopfleisten für die Teile, die an einer Stelle zusammengestellt werden.

+4

Kopfschutz funktioniert nur pro Übersetzungseinheit. – GManNickG

+0

@GMan: Was brauchen Sie mehr? –

+8

Nun, ich weiß nicht über dich; aber meine Projekte bestehen aus mehr als einer Datei. – GManNickG

6

Verwenden Kopfschutz wie Liz schlägt und nicht zu vergessen „inline“ vor Ihrer Funktion Methoden zu setzen.

dh

#ifndef MY_HEADER_H_ 
#define MY_HEADER_H_ 

inline RetType FunctionName(ParamType1 param1, ParamType2 param2) 
{ 
    // Function body 
    return retType; 
} 

#endif 
+0

Nitpick: In C++ gibt es keine Methode. Es gibt Member-Funktionen und Nicht-Member-Funktionen. –

+1

@BillyONeal Das ist nicht wahr; Wie Sie in Stroustrups "Die C++ - Programmiersprache" auf Seite 587 lesen können, werden virtuelle Elementfunktionen manchmal als Methoden bezeichnet. –

4

Außerdem glaube ich, werden Sie jegliche Verwendung von globalen Variablen oder statische Variablen in der Header-only-Bibliothek Code vermeiden müssen.