2010-06-09 74 views
1

您好我有一個類工具,它有靜態變量std :: vector m_tools。C++中的靜態變量定義順序

我可以從其他文件中定義的其他類的全局範圍中插入值到靜態變量中。

實施例:

的Tools.h文件

class Tools 
{ 
public: 
static std::vector<std::vector> m_tools; 

void print() 
{ 
for(int i=0 i< m_tools.size() ; i++) 
std::cout<<"Tools initialized :"<< m_tools[i]; 
} 
} 

tools.cpp文件

std::vector<std::vector> Tools::m_tools; //Definition 

使用寄存器類構造用於置入新的字符串轉換成靜態變量。

class Register 
{ 
public: 
    Register(std::string str) 
{ 
Tools::m_tools.pushback(str); 
} 

}; 

不同類插入字符串靜態變量在靜態變量

first_tool.cpp

//Global scope declare global register variable 


Register a("first_tool"); 



//////// 

second_tool.cpp

//Global scope declare global register variable 


Register a("second_tool"); 

Main.cpp的

void main() 
{ 
Tools abc; 
abc.print(); 
} 

這項工作?

在上面的例子中,只有一個字符串被插入到靜態列表中。問題看起來像「在全局範圍內它嘗試在定義完成之前插入元素」 請讓我知道有沒有什麼方法可以設置靜態定義優先級?或者有沒有其他方法可以做到這一點。

回答

1

靜態全局變量在不同編譯單元中的初始化順序在C++中沒有定義 - 這就是爲什麼你有問題。

解決方法可能是調用一個靜態函數,其中包含第一個靜態變量作爲本地。這樣你就可以迫使它在使用前進行初始化:

// tools.h 

class Tools 
{ 
public: 
    static std::vector<std::vector>& getTools(); 
    ... 
}; 

// tools.cpp 

std::vector<std::vector>& Tools::getTools() { 
    static std::vector<std::vector> tools; 
    return tools; 
} 

... 
class Register 
{ 
public: 
    Register(std::string str) 
    { 
    Tools::getTools().pushback(str); 
    } 
}; 
3

你很可能,在這裏,遇到被稱爲初始化順序的悲劇問題。

問題是全局變量(和靜態類變量是全局變量)的初始化順序在相同的翻譯單元(粗略地說,想法.cpp)內是明確定義的,但在翻譯單元中是完全未定義的。因此,當您嘗試在其中推送項目時,無法保證向量被初始化。

您的解決方案在這裏?使用本地靜態變量:

class Tools 
{ 
public: 
    static std::vector<std::string>& AccessTools() 
    { 
    static std::vector<std::string> Tools; // local static 
    return Tools; 
    } 
private: 
}; 

class Register 
{ 
public: 
    Register(std::string str) 
    { 
    Tools::AccessTools().push_back(str); 
    } 

}; 

這是保證在第一次訪問初始化...雖然這不是(也不可能是)線程安全的;如果您處於多線程狀態,則需要在main之前調用Tools::AccessTools,然後啓動其他線程以保證初始化。