2010-07-20 133 views
1

靜態成員有時會讓我困惑。我已經知道如何初始化內建類型,例如int沿的int myClass::statVar = 10;線,您在.cpp文件放置的東西簡單,但我有以下類似的東西:對象靜態成員的初始化

class myClass 
{ 
public: 
// Some methods... 

protected: 
static RandomGenerator itsGenerator; 
} 

的基本思想是足夠簡單:myClass需要訪問它的一個成員函數的隨機生成器。由於每個對象都相當大,我也只能擁有少數幾個發生器實例。但是,RandomGenerator類型需要「初始化」,可以這麼說,通過調用RandomGenerator::Randomize(),編譯器不允許你這麼做,因爲它不是一個const rvalue(是嗎?)。

那麼我該如何做這項工作?

或者在這種情況下,我應該不使用靜態變量,並以其他方式做?

回答

2

您可以創建包裝類,它將包含RandomGenerator實例,並將在其構造函數中調用RandomGenerator::Randomize

+0

這是壞的。外部類不應該知道發生器的存在。你只改變了它的方式。這是一種解決方法,但它不是解決方案。 – Gangnus 2011-12-19 07:59:43

+0

@Gangnus:不一定。封裝一切都很好,但從外部提供策略沒有任何問題,特別是如果您有可能將更多的責任歸咎於現有的外部類別。 – 2013-08-13 13:51:48

2

把它放在一個私人字段中,公開一個靜態存取器。在訪問器中,如果成員尚未初始化,則對其進行初始化。

+0

我正朝着這個方法努力。我認爲這可能是更好的解決方案,雖然包裝發電機也似乎是一個優雅的想法。 – 2010-07-20 10:16:05

+0

這是壞的。外部類不應該知道發生器的存在。你只改變了它的方式。這是一種解決方法,但它不是解決方案。 – Gangnus 2011-12-19 08:27:15

1

在這些情況下,單身人士實際上是你的朋友,儘管他們還有其他缺點。

+0

是的。我擔心,在C++中它是唯一真正正確的方法。任何來自外太空的深層內部私人領域的設置都是不正確的。外圍空間不應該知道內部發生器及其初始化。 – Gangnus 2011-12-19 07:57:15

+0

@Gangus:查看我的其他評論。這不一定是真的。有時可以從外部提供策略。查看標準庫 - 您可以將分配類型作爲模板參數提供給基本上所有的容器類型,這是完全正確的。 – 2013-08-13 13:52:36

0

它只是一個需要使用RandomGenerator的函數嗎?你可以這樣做了這種方式:

INT MyClass的:: foo的(){ 靜態 RandomGenerator itsGenerator = RandomGenerator ::隨機化() ... }

+0

這不起作用,因爲Randomize不返回生成器。分隔線會導致發生器在您每次輸入塊時被隨機化。 – 2010-07-20 10:17:24

1

如果RandomGenerator是可複製,可使用用於初始化的輔助函數:

RandomGenerator init_rg() { 
    RandomGenerator rg; 
    rg.Randomize(); 
    return rg; 
} 

RandomGenerator myClass::itsGenerator = init_rg(); 
+0

初始化全局(靜態)變量時要小心,因爲不能保證排序。 – doron 2010-07-20 11:24:23

1

只寫其返回引用到適當的隨機RandomGenerator功能,把itsGenerator爲參考發電機:

class myClass 
{ 
public: 
// Some methods... 

protected: 
// make this a reference to the real generator 
static RandomGenerator& itsGenerator; 
public: 
static RandomGenerator& make_a_generator() 
{ 
    RandomGenerator *g=0; 
    g=new RandomGenerator(); 
    g->Randomize(); 
    return *g; 
} 
} 

RandomGenerator& myClass::itsGenerator=myClass::make_a_generator(); 
+0

爲什麼這麼複雜,如果你只能返回一個堆棧分配的實例,讓NRVO負責其餘的部分或者使用一個函數本地'靜態'實例? – 2010-07-20 10:50:12

+0

即使使用NRVO,RandomGenerator也需要一個可訪問的拷貝構造函數。我只是想避免不必要的要求。 – 2010-07-20 10:57:39

0

如果只有myClass需要RandomGenerator,則:

myClass::myClass() 
{ 
    itsGenerator.Randomize(); 
} 

不要緊,如果你重新隨機的隨機數生成器爲每個對象?我假設沒有;-)