2010-06-09 75 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,然后启动其他线程以保证初始化。