1.类模板就是给普通的类加上一个参数,参数可以是未知数据类型标识(如int, string,char, class等),也可以是已知数据类型的值,在下面的第二个例子中,类模板参数实例化会生成一个新的类,这个类中的高与宽是确定的,用该类可以实例化对象,在这个对象中,这两个值也是确定的。
template <typename Type>
template <typename T>
class CQueueItem;
template <typename Type>
class CQueue
{
public:
CQueue();
~CQueue();
Type& remove();
void add(const Type &);
bool is_empty();
bool is_full();
private:
CQueueItem<Type> * head;
CQueueItem<Type> * tail;
};
template <int hi, int wid>
class Screen {
public:
Screen() : _height( hi ), _width( wid ), _cursor ( 0 ),
_screen( hi * wid, `#' )
{ }
// ...
private:
string _screen;
string::size_type _cursor;
short _height;
short _width;
};
typedef Screen<24,80> termScreen;
2.另外一个问题是效率问题,看下面这个例子
termScreen hp2621;
template <class Type>
class QueueItem {
// ...
public:
// 可能效率很低
QueueItem( const Type &t ) {
item = t; next = 0;
}
};
如果模板实参是一个具有构造函数的类例如string 它将导致item 被初始化两次
在QueueItem 的构造函数体执行之前string 的缺省构造函数被调用来初始化item 然后
新构造的item 又被按成员赋值在QueueItem 构造函数的定义中我们只需在构造函数成员
初始化表中显式地初始化item 就可以解决这个问题:
template <class Type>
class QueueItem {
// ...
public:
// 在构造函数成员初始化表中初始化 item
QueueItem( const Type &t )
: item(t) { next = 0; }
};
3.注意模板声明与定义的区别
4.实参的类型与大小要确定,在实例化类模板时要注意实参一定要有确知类型和大小.
CQueue myQueue;
错误,类型不确定,这种错误比较容易避免,因为词法上通不过。
再看下一下:
template <int *ptr> class BufPtr { ... };
BufPtr< new int[24] > bp;
错误,因为那么它的实例将导致编译错误因为来自操作符new()调用结果的指针值只有到运行时刻才能被知道,这样编译时通不过,因为"模板实参不能在编译时刻被计算出来",因为编译时要分配内存,所以,类型与大小必须要确知。
类模板学习总结
最新推荐文章于 2022-04-11 14:30:48 发布