2008-12-23 27 views
5

讓我們考慮一個C++類。在執行開始時,我想從XML文件讀取一組值,並將它們分配給該類的數據成員中的7個。這些值在整個執行過程中不會改變,它們必須由所討論的類的所有對象/實例共享。靜態數據成員是實現這種行爲最優雅的方式嗎? (當然,我不認爲是全局變量)我應該使用靜態數據成員嗎? (C++)

回答

3

聽起來像一個很好的使用靜態變量給我。您將這些參數用作固定參數而不是變量,並且這些值合法地需要共享。

3

靜態成員可以在這裏工作,完全可以接受。另一個選擇是對持有這些成員的類使用singleton pattern以確保它們只構造/設置一次。

5

正如其他人所說,在這種情況下使用靜態成員似乎是適當的。請記住它不是萬無一失的;全局數據的一些問題適用於靜態成員:

  • 您無法控制靜態成員的初始化順序,因此您需要確保沒有全局變量或其他靜態引用指向這些對象。有關更多詳細信息,請參閱this C++ FAQ Question以及避免此問題的一些提示。
  • 如果你在多線程環境中訪問它們,你需要確保成員在你產生任何線程之前完全初始化。
+0

這些值是在執行開始時設置的,所以這些問題在這裏並不適用。 – 2008-12-23 20:54:02

+0

大衛,他們會一旦決定將xml對象作爲靜態對象放置在某處。銷燬的順序也是相關的。請參閱下面的答案。 – 2008-12-23 23:23:09

2

聽起來像是靜態類成員的適當使用。只是不要忘記,它們是具有名稱空間和(可能)一些保護的全局變量。因此,如果有可能您的應用程序有一天會演變成單獨的「環境」或某些需要這些環境變量的東西,那麼您已將自己繪製在一個角落。

按照Rob的建議,考慮使用一個單例,該單例稍後會變得更容易變成某種託管環境變量。

3

這不是一個乾淨的設計。靜態類成員是全局狀態和global state is bad

它可能給你造成麻煩,如果這是一個小型到中型項目,你不具備自動測試高的目標,但既然你問:還有更好的方法。

一個更清潔的設計是爲類創建一個工廠,並讓工廠在構造它時將七個變量傳遞給類。 Factory的責任是確保所有實例共享相同的值。

這樣,你的課就成爲可測試的,你已經正確地區分了你的顧慮。

PS。 Don'tusesingletonseither

0

只要你認爲可測試性的,你有另一種方式來設置靜態變量,除了讀入文件,再加上你不靠數據benig不變的過程中的整個執行時間 - 你應該精細。

我發現,當你設計你的代碼編寫測試思維可以幫助你保持代碼的良好分解和可重複使用。

1

是的,靜態數據成員就是你要找的。但是你必須注意你的靜態變量的初始化/破壞順序。 C++中沒有任何機制可以確保您的靜態變量在跨翻譯單元使用之前被初始化。爲了安全起見,使用看起來像單例模式的東西,並且知道解決這個問題。它的工作原理是:

  1. 所有靜態對象都是在完成任何xml_stuff實例的構建之後完全構建的。
  2. 在C++中銷燬靜態對象的順序與其構造完成相反(當它們的構造函數完成執行時)。

代碼:

class xml_stuff { 
public: 
    xml_stuff() { 
     // 1. touch all members once 
     // => 2. they are created before used 
     // => 3. they are created before the first xml_stuff instance 
     // => 4. they will be destructed after the last xml_stuff instance is 
     //  destructed at program exit. 
     get_member1(); 
     get_member2(); 
     get_member3(); 
     // ... 
    } 

    // the first time their respective function is called, these 
    // objects will be created and references to them are returned. 
    static type1 & get_member1() { static type1 t; return t; } 
    static type2 & get_member2() { static type2 t; return t; } 
    static type1 & get_member3() { static type1 t; return t; } 
    // ... all other 7 members 
}; 

現在,get_memberN由xml_stuff返回的對象::()是任何xml_stuff實例的整個生命週期有效的,因爲任何成員被任何xml_stuff實例之前建造的。使用純靜態數據成員,您無法確保,因爲在C++中未定義跨翻譯單元的創建順序。

2

當時我想從一個 XML文件讀出一組值,並將其分配到這個類的 數據成員的7開始執行。這些 值在執行整個 期間不會更改,並且它們必須由有問題的 類的所有對象/實例共享 。

黑體字的句子是這裏的踢球者。只要該語句成立,靜態變量的使用即可。這將如何執行?

很難。所以,如果您現在使用該聲明總是如此,請繼續。如果你想和未來的開發者(或你)一樣使用錯誤的類(比如在程序中途讀取另一個XML文件),那麼就像Rasmus Farber所說的那樣。