2010-04-29 107 views
8

我有這些C++類:靜態變量在基類和繼承

class Base 
{ 
protected: 
    static int method() 
    { 
     static int x = 0; 
     return x++; 
    } 
}; 

class A : public Base 
{ 

}; 

class B : public Base 
{ 

}; 

請問x靜態變量之間AB被共享,或將它們中的每一個有它自己的獨立x可變(這是我想要的)?

+2

這不是你可以用編譯器和一些測試代碼快速檢查的東西嗎? – 2010-04-29 12:01:37

+2

@ttmrichter:如果有任何懷疑,可能是依賴於實現的。而當你檢查它不是時,你找到了答案。 – 2010-04-29 12:06:20

+0

@ttmrichter我懷疑這個變量會被共享,但我也想看看是否有人有另一種方式來解決我的問題:) – Meh 2010-04-29 12:10:01

回答

14

在整個程序中只會有一個x的實例。一個很好的解決辦法是使用CRTP

template <class Derived> 
class Base 
{ 
protected: 
    static int method() 
    { 
     static int x = 0; 
     return x++; 
    } 
}; 

class A : public Base<A> { }; 
class B : public Base<B> { }; 

這將創建一個不同的Base<T>,因此明顯x,每個從它派生類。

您可能還需要一個「Baser」基礎來保留多態性,正如Neil和Akanksh指出的那樣。

+0

不錯,你在我準備提交時發佈:)。 – Akanksh 2010-04-29 12:00:43

+2

但是你沒有得到的是多態,如果這是必需的。 – 2010-04-29 12:00:46

+0

謝謝,我忘了我解決了很多年前非常類似的問題,也與CRTP :) – Meh 2010-04-29 12:11:29

3

將只有一個,所有三個類共享。如果你想要單獨的實例,你將不得不在派生類中創建單獨的函數。

2

前者。本地靜態變量綁定到包含它們的方法,並且method存在於所有子類的一個化身中(實際上,對於整個應用程序,即使程序的其餘部分沒有看到該方法)。

1

變量將被共享 - 它是每個函數 - 在這種情況下,它所屬的函數是Base::method()。但是,如果class Base是一個模板類,則您將獲得class Base模板的每個實例化(每個唯一的一組實際模板參數)的變量的一個實例 - 每個實例化都是一個新函數。

1

如果您將X設爲靜態,那麼它將在所有子類中共享。功能沒有問題是靜態的。

3

我敢肯定這將A和B

之間共享,如果你想獨立的變量,你可以使用「奇異遞歸模板模式」,如:

template<typename Derived> 
class Base 
{ 
protected: 
    static int method() 
    { 
     static int x = 0; 
     return x++; 
    } 
}; 

class A : public Base<A> 
{ 

}; 

class B : public Base<B> 
{ 

}; 

當然,如果你想多態,你必須定義一個甚至是「卑劣」類基地從派生,如Base<A>不同於Base<B>,如:

class Baser 
{ 
}; 

template<typename Derived> 
class Base : public Baser 
{ 
protected: 
    static int method() 
    { 
     static int x = 0; 
     return x++; 
    } 
}; 

class A : public Base<A> 
{}; 

class B : public Base<B> 
{}; 

現在A和B也可以是多態的。