类模板的静态数据成员
类模板中可以声明静态数据成员,静态数据成员的定义必须出现在类模板的定义之外。
类模板的每个实例都有自己的一组静态数据成员。每个静态数据成员实例都与一个类模板实例相对应。因此,一个静态数据成员的实例总是通过一个特定的类模板实例被引用
实例
#ifndef Water_H
#define Water_H
#include <iostream>
template<typename T>
class Water
{
public:
Water();
~Water();
void Push(T);
void Pop();
void print();
private:
T *ptr = nullptr;
unsigned short value = 0;
static unsigned short MAX;
};
#endif
template<typename T>
unsigned short Water<T>::MAX = 10;
template<typename T>
Water<T>::Water()
{
ptr = new T[sizeof(T)*MAX];
}
template<class T>
Water<T>::~Water()
{
if (ptr)
delete[]ptr;
ptr = nullptr;
}
template<class T>
void Water<T>::Push(T va)
{
if (value < MAX)
ptr[value++] = va;
}
template<class T>
void Water<T>::Pop()
{
if (value > 0)
--value;
}
template<class T>
void Water<T>::print()
{
for (unsigned short index = 0; index < value; std::cout << "index:" << index << " value:" << ptr[index] << "\n", ++index);
}
#include "Water.h"
int main()
{
Water<char> water;
for (unsigned short index = 0; index < 5; water.Push((char)(index + 97)) , ++index);
water.print();
water.Pop();
water.print();
system("pause");
return 0;
}
类模板的友元
有3种友元声明可以出现在类模板中:
(1)非模板友元类或友元函数。不使用模板参数的友元类或友元函数是类模板的所有实例的友元。
(2)绑定的友元类模板或函数模板。使用模板类的模板参数的友元类和友元函数与实例化后的模板类之间是一一对应的关系。
举例
#include <iostream>
template<typename Type> class Queue;
template<typename T>
class QueueItem
{
public:
QueueItem(const T &data) : item(data) {}
~QueueItem() { next = nullptr; }
friend class Queue<T>;
private:
T item;
QueueItem *next = nullptr;
};
template<typename Type>
class Queue
{
public:
Queue() {}
~Queue() {}
Type remove();
void add(const Type &);
bool isEmpty()const;
void print();
private:
QueueItem<Type> *front = nullptr, *back = nullptr;
};
template<typename Type>
bool Queue<Type>::isEmpty() const
{
return front ? false : true;
}
template<typename Type>
void Queue<Type>::add(const Type &data)
{
QueueItem<Type> *item = new QueueItem<Type>(data);
if (front)
{
QueueItem<Type> *_front_ = front;
while (_front_->next)
{
_front_ = _front_->next;
}
_front_->next = item;
}
else
front = item;
}
template<typename Type>
Type Queue<Type>::remove()
{
Type result = 0;
if (front)
{
QueueItem<Type> *_front_ = front, *_front_pre = _front_;
while (_front_->next)
{
_front_pre = _front_;
_front_ = _front_->next;
}
if (_front_ == front)
{
front = nullptr;
return result;
}
if (_front_)
{
result = _front_->item;
delete _front_;
}
_front_pre->next = nullptr;
_front_ = nullptr;
}
return result;
}
template<typename Type>
void Queue<Type>::print()
{
QueueItem<Type> *_front_ = front;
while (_front_)
{
std::cout << _front_->item << " ";
_front_ = _front_->next;
}
_front_ = nullptr;
}
#include <iostream>
#include "Queue.h"
int main()
{
Queue<int> queue;
std::cout << "queue.isEmpty():" << (queue.isEmpty() ? "yes" : "no") << std::endl;
for (unsigned short index = 0; index < 10; queue.add(index), ++index);
std::cout << "queue.isEmpty():" << (queue.isEmpty() ? "yes" : "no") << std::endl;
queue.print();
std::cout << std::endl << "----------------------------------------" << std::endl;
for (unsigned short index = 0; index < 20; queue.remove(), ++index);
std::cout << "queue.isEmpty():" << (queue.isEmpty() ? "yes" : "no") << std::endl;
queue.print();
std::cout << std::endl << "----------------------------------------" << std::endl;
for (unsigned short index = 0; index < 4; queue.add(index), ++index);
std::cout << "queue.isEmpty():" << (queue.isEmpty() ? "yes" : "no") << std::endl;
queue.print();
system("pause");
return 0;
}
(3)非绑定的友元类模板或函数模板。这时友元类模板或函数模板有自己的模板参数,因此和模板类实例之间形成一对多的映射关系,即对任一个模板类的实例,友元类模板或函数模板的所有实例都是它的友元。C++标准化之前的编译器不支持这种友元声明。
template <class T>
class MTC
{
public:
friend void foo() :
// foo()是所有MIC模板的实例的友元
friend void goo<T>(vector<T>)
// 每个实例化的MIC类都有一个相应的 goo()友元实例
template <class Type> friend void hoo(MIC<Type> );
// 对MIC的每个实例,hoo()每个实例都是它的友元
};
关注
笔者 - jxd (码农总动员)