模板类的static成员
与其它任何类相同,模板类可以声明static成员:
template <typename T> class Foo { public: static std::size_t count() {return ctr;} //其它接口成员 private: static std::size_t ctr; };
在这段代码中,Foo是一个类模板,它有一个名为count的public static成员函数和一个名为ctr的private static的数据成员。每个Foo的实例都有自己的static成员实例。即,对任意给定类型X,都有一个Foo<X>::ctr和一个Foo<X>::count成员。所有Foo<X>类型的对象共享相同的ctr对象和count函数。例如:
//实例化static成员Foo<std::string>::ctr和Foo<std::string>::count Foo<std::string> fs; //所有三个对象共享相同的Foo<int>::ctr和Foo<int>::count成员 Foo<int> fi, fi2, fi3;
与任何其它static数据成员相同,模板类的每个static数据成员必须有且仅有一个定义。但是,模板类的每个实例都有一个独立的static对象。因此,与定义模板成员函数相似,我们将static数据成员也定义为模板:
template <typename T> std::size_t Foo<T>::ctr = 0;
与类模板的其它成员类似,定义的开始部分是模板的参数列表,随后是我们定义的成员的类型和名字。与往常一样,成员名包括成员的类名,对于模板生成的类来说,类名包括模板实参。因此,当使用一个特定的模板实参类型实例化Foo时,将会为该类类型实例化一个独立的ctr,并将其初始化为0。
与非模板类的静态成员相同,我们可以通过类类型对象来访问一个类模板的static成员,也可以使用作用于运算符直接访问成员。当然,为了通过类来直接访问static成员,我们必须引用一个特定的实例:
Foo<int> fi; //实例化Foo<int>类和static数据成员ctr auto ct = Foo<int>::count(); //实例化Foo<int>::count ct = fi.count(); //使用Foo<int>::count ct = Foo::count(); //错误:使用哪个模板实例的count?
类似于任何其它成员,一个static成员函数只有在使用时才会实例化。