2012-08-06 108 views
0

我有一個關於靜態變量或其他方式的問題。持久化類變量

我有一個主類PatternMatcher。我有幾個衍生單位,取決於使用什麼匹配器。現在每個子類都需要存儲一個浮點向量,但是在每個類中它是不變的。初始化過程中讀取該矢量的數據,最大可達1GB(最小的是1MB,最大的是1GB)。 目前當我有例如Matcher_A的兩個實例時,它會分配兩次內存。我事先不知道哪些匹配器將被使用(每次運行它將是三個匹配器,並且您可以多次使用相同的匹配器)。我寧願在運行時不檢查想要的匹配器是否已經在某處進行了初始化,因爲這需要爲我所做的每個更改都添加額外的代碼。

目前我分配3個匹配器與

PatternMatcher* a = new PMMatcherA(); 
PatternMatcher* b = new PMMatcherB(); 
PatternMatcher* c = new PMMatcherC(); 

,但因爲它們是用戶選擇的,它可能發生的是A和C是例如相同的。當我通過typeid(a).name();運行支票時,它會給我PatternMatcher作爲結果,而不管我用什麼課程開始。 PatternMatcher基本上純粹是一個虛擬類。

我一直認爲靜態意味着一個變量在不同的分配上是不變的,但是當我將我的向量定義爲靜態時,我會得到一個鏈接器解析錯誤。在之前的迭代中,我將這些向量設置爲全局的,但希望將它們本地化爲其類。

我需要使用哪些關鍵字來使初始化的向量可用於下一次初始化?簡單的檢查向量大小是否大於0就足夠了,但是每個對象都使用自己的向量。

回答

1

static關鍵字長的路要走 - 這將爲整個班級存儲一份成員的完整副本。你缺少的是在編譯模塊中實際聲明這樣的靜態,以便鏈接器可以使用它。例如:

header file foo.h

struct Foo { 
    static int s_int; 
} 

source file foo.cpp

#include "foo.h" 
int Foo::s_int; // optionally =0 for initialization 

第二部分是至關重要的,因爲這將分配用於對象被用作靜態成員的存儲器空間。

請記住,雖然,:

  • static成員將所有之前被初始化main(),這意味着你的1GB的數據將被不管是否有人曾經使用了特定的類閱讀
  • 您可以解決上述問題,但你必須要檢查,如果數據加載和初始化在運行時發生

但是,您還有其他選擇。如果你按原樣存儲你的浮點數(例如,每個32位二進制格式),你可以簡單地將這些文件「映射」到內存空間,並像訪問它們時已經加載一樣訪問它們 - 操作系統將負責加載需要時將適當的4K頁面放入RAM中。

閱讀http://en.wikipedia.org/wiki/Mmap

+0

謝謝,這做到了。只有在第一次調用匹配器後,向量本身才會與數據堆疊起來,因此最初每個向量都只有sizeof(向量),這非常好。再次感謝! – SinisterMJ 2012-08-06 11:18:18

1

是的,static是你所需要的。您可以使用它像這樣:

class MyClass 
{ 
private: 
    static std::vector<float> data_; 
}; 

std::vector<float> MyClass::data_; 

請注意,在類本身只聲明靜態變量。但你也需要定義他們以外的類恰好一次。這就是爲什麼我們有行std::vector<float> MyClass::data_;,如果你忽略了這一點,你會有鏈接錯誤。

在此之後,MyClass類的對象將共享相同的data_載體。

可以操作它無論是從類的任何對象:

MyClass a; 
a.data_.push_back(0); 

或通過類名:

MyClass::data_.push_back(0);

1

更多mmap當我定義我的矢量爲靜態,我會得到一個鏈接決心 錯誤。

這是因爲你聲明瞭靜態變量(在你的頭文件中),但你永遠不會在你的一個實現文件(.cpp)中明確地初始化它。

例如:

//AClass.h 
class AClass 
{ 
    private: 
    static std::vector<int> static_vector; 

}; 

,並在.cpp實現文件:

std::vector<int> AClass::static_vector;