我有一个像这样的头文件中定义的模板类.这里我也定义了一个静态变量:
#ifndef TEST1_H_ #define TEST1_H_ void f1(); static int count; templateclass MyClass { public: void f() { ++count; } }; #endif
我已经在不同的cpp文件中定义了main()函数,如下所示:
int main(int argc, char* argv[]) { MyClassa; a.f(); f1(); cout<<"Main:" << count << "\n"; return 0; }
我在不同的cpp文件中实现了函数f1(),如下所示:
void f1() { MyClassa; a.f(); cout<<"F1: " < 当我用VC6编译它时,输出为"F1:0 Main:2".这怎么可能?另外,一般情况下,如果我想将静态变量与模板一起使用,我应该如何处理?
1> Todd Gamblin..:您获得了同一个变量的两个副本,因为您已在头文件中声明了一个静态变量.当你以
static
这种方式声明一个全局变量时,你会说它是编译单元(.o
文件)的本地变量.由于您在两个编译单元中包含标头,因此您将获得两个副本count
.我认为你真正想要的是一个与模板类的每个实例相关联的静态模板成员变量.它看起来像这样:
templateclass MyClass { // static member declaration static int count; ... }; // static member definition template int MyClass ::count = 0; 这将为您计算模板的每个实例化.也就是说,你就会有一个数
MyClass
,MyClass
,MyClass
,等f1()
现在看起来是这样的:void f1() { MyClassa; a.f(); cout<<"F1: " << MyClass ::count <<"\n"; }
如果要对MyClass的所有实例化进行计数(无论其模板参数如何),都需要使用全局变量.
但是,您可能不希望直接使用全局变量,因为在初始化之前存在使用它的风险.你可以通过创建一个返回对你的计数的引用的全局静态方法来解决这个问题:
int& my_count() { static int count = 0; return count; }然后从你的类中访问它,如下所示:
void f() { ++my_count(); }这将确保计数在使用之前被初始化,无论您从哪个编译单元访问它.有关更多详细信息,请参阅有关静态初始化顺序的C++ FAQ.