2013-11-22 39 views
0

我希望有一些全球地圖,這應該在很多地方都可以使用,一些常用的小功能。這是我如何組織它。C++程序組織代碼,避免「的多個定義。」

util.h

#ifndef UTIL_H 
#define UTIL_H 

#include <unordered_map> 

namespace util { 

extern std::unordered_map<std::string, short> rgb2short { 
    { "000000", 0 }, 
    { "800000", 1 }, 
    { "008000", 2 }, 
    { "808000", 3 }, 
    { "000080", 4 }, 
    /* ... and so on */ 
}; 

short some_util_func() { 
    /* some util code here */ 
} 

} 
#endif 

somefile.cpp

#include "util.h" 

/* usage of util::rgb2short and util::some_util_func() */ 

someotherfile.cpp

#include "util.h" 

/* usage of util::rgb2short and util::some_util_func() */ 

小樣iler沒有接受,並回答wiith衆多multiple definition of 'util::rgb2short'

所以,問題是這樣的util事情應該如何更好地組織。

+1

刪除extern關鍵字 - 你在util.h中提供了一個定義,而不是在外部 – OllieB

+0

你爲什麼試圖在你的頭文件中初始化你的地圖。爲什麼你的函數在你的頭文件中沒有被內聯呢? (對於你想要做的事情,這仍然不是一個合適的解決方案)。 – WhozCraig

回答

3

至少當涉及到數據,標題應該只包括聲明。該聲明必須包含extern關鍵字(你沒看錯的部分)必須包含初始化。

唯一的例外(這不是一個普遍的話)是,如果你想要的數據,以便把包含在標題中的每個翻譯單元的單獨副本。在這種特殊情況下,您需要指定數據爲static而不是extern

在你的情況,util.h應該只包含的rgb2short外部聲明。該定義(包括初始化程序)應該在一些.cpp文件中(例如,util.cpp)。同樣,util.h不應該包含some_util_func()的定義。它應該只包含一個聲明,並且(再次)將該定義放置在源文件中,例如util.cpp

所以,util.h最終會看起來像這樣:

#ifndef UTIL_H 
#define UTIL_H 

#include <unordered_map> 

namespace util { 

extern std::unordered_map<std::string, short> rgb2short; 

short some_util_func(); 

} 
#endif 

Util.cpp應該是這樣的:

#include "util.h" 

namespace util { 

std::unordered_map<std::string, short> rgb2short { 
    { "000000", 0 }, 
    { "800000", 1 }, 
    { "008000", 2 }, 
    { "808000", 3 }, 
    { "000080", 4 }, 
    /* ... and so on */ 
}; 

short some_util_func() { 
    /* some util code here */ 
} 

} 

,那麼你會#include "util.h"就像你做了,但也鏈接util.obj(或util.o,或任何對象文件被命名)與其他對象文件。

1

你應該把在標題中聲明定義在源文件中,就像這樣:

util.h

#ifndef UTIL_H 
#define UTIL_H 

#include <unordered_map> 

namespace util { 
    extern std::unordered_map<std::string, short> rgb2short; 
} 

#endif 

util.cpp

#include "util.h" 

namespace util { 

    std::unordered_map<std::string, short> rgb2short { 
     { "000000", 0 }, 
     { "800000", 1 }, 
     { "008000", 2 }, 
     { "808000", 3 }, 
     { "000080", 4 }, 
     /* ... and so on */ 
    }; 

} 

這將避免這些錯誤。對於該函數,可以將其標記爲inline,並將代碼放在標題中,或者將標記放在標題中(不需要extern),並將正文放入CPP文件中。