当设计开发一个类的时候,程序员通常需要在类的内部定义一些静态变量。在通常情况下,你会在一个类的头文件中定义一个静态变量并在源代码程序中初始化,如下所示:
// File.h
class File
{
// . . . code
private:
static char DELIMETER;
}
// File.cpp
char File:
ELIMETER = "/";
然而,这一方法并不适用于模板类。模板类通常位于头文件中。生成一个原文件并没有太多的用处,因为你不能为所用的模板参数初始化。
// Array.h
template< class T>;
class Array
{
// . . .
private:
// hold all instances of this type (T) in an array
static std::vector< Array< T>; *>; s_aAllInstances;
};
// Array.cpp
// illegal C++
template< class T>;
std::vector< Array< T>; >; Array< T>;::s_aAllInstances;
然而,C++允许静态函数在模板中操作,而在一个静态函数中,你可以调用一个静态变量。
如下所示:
template< class T>;
class Array
{
//...
private:
typedef std::vector< Array< T>;*>; ElementsArray;
static ElementsArray & s_Elements()
{
static ElementsArray s_array;
return s_array;
}
};
这一技巧功能非常强大,因为对于Array< int>;,你必须提供Array<
int>;::s_Elements;对于rArray< std::string>;,你必须担任 Array<
std::string>;::s等。
这里你必须完成下面的两个步骤:
在模板类中必须有一个模板函数(不是变量);我们建议你以变量名的形式来为它命名。
在模板函数中添加静态数据。
下面的范例包含了Array< T>;类,这一类在内部里把每一数组定义为类型T。当某一类型被生成或删除时,它会显示出数组元素个数及其类型。
#include <vector>;
#include <algorithm>;
#include <iostream>;
template< class T>;
struct Type;
template<>;
struct Type< int>;
{
static const char * name() { return "int"; }
};
template<>;
struct Type< long>;
{
static const char * name() { return "long"; }
};
template<>;
struct Type< std::string>;
{
static const char * name() { return "std::string"; }
};
template<>;
struct Type< float>;
{
static const char * name() { return "float"; }
};
/*
holds internal references to its objects
(of Type T)
*/
template< class T>;
class Array
{
public:
Array()
{ AddMe(); }
Array( const Array &
{ AddMe(); }
~Array()
{ DeleteMe(); }
private:
void AddMe()
{
s_Elements().push_back( this);
std::cout
<< "We have added one element of type "
<< Type< T>;::name() << std::endl;
std::cout
<< "We have now " << s_Elements().size()
<< " " << Type< T>;::name() << " elements" << std::endl;
}
void DeleteMe()
{
ElementsArray::iterator itFound =
std::find( s_Elements().begin(), s_Elements().end(), this);
if ( itFound != s_Elements().end())
{
s_Elements().erase( itFound);
}
std::cout
<< "We have deleted one element of type "
<< Type< T>;::name() << std::endl;
std::cout
<< "We have now " << s_Elements().size()
<< " " << Type< T>;::name() << " elements" << std::endl;
}
private:
// note: we're treating it as an internal variable
typedef std::vector< Array< T>;*>; ElementsArray;
static ElementsArray & s_Elements()
{
static ElementsArray s_array;
return s_array;
}
};
int main(int argc, char* argv[])
{
Array< int>; int1;
Array< int>; int2;
Array< long>; long1;
Array< long>; long2;
Array< std::string>; str1;
Array< std::string>; str2;
Array< float>; float1;
Array< float>; float2;
Array< float>; float3;
Array< int>; int3;
Array< long>; long3;
Array< std::string>; str3;
return 0;
}