之前
const char * const g_someString = "Hello";
你需要將其聲明爲extern
(例如通過包括頭部),因爲const
命名空間層次變量的缺省內部鏈接。
也就是說,你可以在標題中定義字符串。單獨的編譯讓您可以修改字符串而不會重建大量文件,但除此之外,恕我直言,這是過早的優化。
爲了使字符串定義在頭正式安全的inline
功能,如果這是需要的,你需要的字符串(或至少是指針)有extern
聯動。一種方法是在一個定義規則中利用特殊的模板豁免。例如。像這樣:
// Perhaps best generated by some code generation facility:
template< class Dummy >
struct Strings_
{
static char const* const some_string;
static char const* const some_other_string;
};
template< class Dummy >
char const* const Strings_<Dummy>::some_string = "Blah!";
template< class Dummy >
char const* const Strings_<Dummy>::some_string = "Oh, well.";
using Strings = Strings_<void>;
然後使用像
inline void foo() { cout << Strings::some_string << endl; }
這裏Strings::some_string
指針會在所有的翻譯單位相同。
另一種方法是定義inline
函數中的字符串。然後你可以使用例如枚舉來命名它們。
enum String_id { some_string, some_other_string };
inline
auto strings(String_id const id)
-> char const*
{
switch(id)
{
case some_string: return "Blah!";
case some_other_string: return "Oh, well.";
}
assert(false); // Should never get here.
}
與使用像
inline void foo() { cout << strings(some_string) << endl; }
的inline
功能有extern
聯動,因此它在所有的翻譯單位相同。
在_constants.cpp_ – Karthik
中的定義確保'constants.cpp'包含'constants.h'(並且沒有循環依賴關係) –
'void main'的定義之前,鏈接器錯誤消失了_extern_聲明在C++中是非法的,即使你的編譯器提供了一個不合規的擴展名,編寫依賴於這些擴展名的代碼也是不好的 –