2013-03-07 68 views
3

我有一個C++類聲明瞭一個單一的靜態成員。整個類都包含在一個頭文件中,我寧願避免創建一個.cpp文件來簡單地包含靜態成員定義。我一直試圖使用靜態關鍵字(在C的意義上)和匿名命名空間,這兩個應該給頭文件靜態鏈接(asfaik)聲明的變量,但都沒有辦法工作,任何人都可以給我一個解決方案問題?聲明的靜態成員與靜態鏈接

struct ServiceType {} ; 
struct Transport 
{ 
    static ServiceType service ; 
}; 

//error: definition of ‘Transport::service’ is not in namespace enclosing ‘Transport’ 
//namespace { ServiceType Transport::service ; } 

//error: ‘static’ may not be used when defining a static data member 
//static ServiceType Transport::service ; 
+0

'static'值不一定意味着靜態鏈接。它恰好是相同的關鍵字,但其含義完全不同。你不能有靜態鏈接的成員。所以你想要的是不可能的。你*有*在某處定義符號。沒有辦法繞過它。 – 2013-03-07 13:16:21

+0

我理解靜態關鍵字的多種用法之間的區別 – 2013-03-07 13:32:24

回答

4

有它,如果你堅持鏈接錯誤,如果目標只是不必創建一個.cpp文件時, 簡單的解決辦法可能是包裝靜態數據 成員在一個內聯靜態成員函數中。換句話說, 是這樣的:

struct Transport 
{ 
    static ServiceType& service() 
    { 
     static ServiceType theData; 
     return theData; 
    } 
}; 

當然,你必須使用語法service(),而 不僅僅是service,訪問它。當應用於成員

+0

這很好,謝謝。 – 2013-03-07 15:07:03

0

匿名命名空間在整個編譯單元中可見。如果您將標頭包含在多個源文件中,則最終會有多個名爲Transport :: service的符號。這是行不通的,因爲你會從鏈接器得到一個symbol already defined錯誤。

恐怕C++的工作方式不允許您在不移動.cpp文件中service符號的定義的情況下襬脫此問題。

所以,在.cpp文件,無論是做Transport::ServiceType service;,或者如果你不想service是一個命名空間的一部分在.cpp頁眉和ServiceType service;extern ServiceType service;

1

不能定義具有內部鏈接的靜態成員。

如果定義在頭文件中的靜態成員service,你將不得不在每一個源,在這裏你有這個頭文件的實例。如果這不是一個問題,可以環繞整個struct Transport

namespace { 
struct Transport 
{ 
    static ServiceType service ; 
}; 

ServiceType Transport::service; 
} 
+0

您的意思是靜態生命週期,而不是靜態鏈接。 (沒有靜態鏈接這樣的東西。) – 2013-03-07 14:01:41

+0

使用匿名命名空間不會起作用。他將在每個包含他的頭文件的翻譯單元中完成一個完全不同的類(和靜態實例)。 – 2013-03-07 14:02:52

+0

@JamesKanze不,我的意思是聯繫而不是生命。儘管如此,重寫爲標準術語。 – 2013-03-07 14:27:47

0

一個匿名的命名空間嘗試

ServiceType Transport::service ; 

這是錯誤的:

namespace { ServiceType Transport::service ; } //You are adding it in an unnamed namespace, rather than whatever namespace Transport is actually in - presumably the global namespace 

這是錯誤的:

static ServiceType Transport::service ; // You dont need the static here, only in the struct. 

我希望你會得到在頭雖然