2013-10-02 49 views
1

的我有一些像這樣的代碼:靜態數據成員但類型派生

// Factory.h

template <typename TFactoryTable, typename TBaseProduct> 
class FactoryTable { 
public: 
    static TFactoryTable instance; 
}; 

template <typename TFactoryTable, typename TBaseProduct> 
TFactoryTable FactoryTable<TFactoryTable, TBaseProduct>::instance; 

// foo.h中

class BaseFoo {}; 
class FooFactoryTable : public FactoryTable<FooFactoryTable, BaseFoo> {}; 

// Bar.h

class BaseBar {}; 
class BarFactoryTable : public FactoryTable<BarFactoryTable, BaseBar> {}; 

// main.cpp中

void test() { 
    auto& t = FooFactoryTable::instance; 
} 

我把FactoryTable <>的定義靜態成員「實例」,這樣,我可以迫使工廠表(FooFactoryTable,BarFactoryTable,...)使用相同的方式來定義它的單身。這些代碼由Visual Studio 2012(V110)編譯好,但編輯器(智能感知未編譯器)測試報告FooFactoryTable錯誤::實例():

Error: class "FooFactoryTable" has no member "instance" 

如果我改變聲明&定義實例來是「FactoryTable」類型(不是TFactoryTable),那麼編輯器不會報告錯誤。所以我擔心,這是(編譯好)一個msvc唯一的功能,或標準的c + +功能?因爲代碼的目標平臺是android和iphone,並且需要由gcc編譯。

回答

1

Intellisense很容易被更復雜的構造(尤其是預處理器或模板)所迷惑,並喜歡報告虛假錯誤。像這個。使用TFactoryTable作爲靜態成員類型的代碼是100%合法的C++。

+0

我很好奇:如果Foo.h包含在1個以上的編譯單元中,那麼會不會出現鏈接器錯誤,指出有'FooFactoryTable :: instance'的多個定義?或者是否會爲每個單元存在多個「私有」實例,湮沒單身人士的使用? –

+0

@king_nak只有一個實例,並且定義*必須*存在於每個使用它的翻譯單元中。編譯器/鏈接器必須使其工作。 – Angew

+0

好的,鏈接器的工作很好......我知道模板的定義必須在每個單元中出現,但不知道它是以靜態方式工作的。因爲如果沒有模板,那麼靜態實例必須在*完全一個*單元中定義! –