C++ 类模板

全文为个人理解总结用

《C++ primer plus》14章 类模板概念
有点理解不来。梳理一遍。

  • 核心要义:模板,是为了满足重用代码的需求。
    (比如一套代码,多种数据类型皆可使用。)
  • 百度百科:
    泛型即是指具有在多种数据类型上皆可操作的含义,与模板有些相似

语法

类模板的声明和定义
  • 一个普通的Stack类(栈类)
    Stack.h
typedef unsigned long Item;

class Stack
{
private:
	enum {MAX = 10};
	Item item[max];
	int top;
public:
	Stack();
	bool isempty() const;
	bool isfull() const;
	bool push(const Item & item};
	bool pop(Item & item);
}
  • 声明为类模板的Stack类
    Stack.h

template <typename Type>//早期编译器需要这种写法template <class Type >
class Stack
{
private:
	enum {MAX = 10};
	Type item[max]; //(声明的唯一区别在 item 的数据类型上)
	int top;
public:
	Stack();
	bool isempty() const;
	bool isfull() const;
	bool push(const Item & item};
	bool pop(Item & item);
}

Stack.cpp

template <typename Type>
Stack<Type>::Stack()
{
	top = 0;
}

template <typename Type>
bool Stack<Type>::isempty()
{
	return top == 0;
}

template <typename Type>
bool Stack<Type>::isfull()
{
	return top == MAX;
}

template <typename Type>
bool Stack<Type>::push(const Type & item)
{
	if(top < MAX)
	{
		items[top++] = item;
		return true;
	}
	else
	{
		return false;
	}
}

template <typename Type>
bool Stack<Type>::pop(Type & item)
{
	if(top > 0)
	{
		item = items[--top];
		return true;
	}
	else
	{
		return false;
	}
}
使用上的区别
  • 一个普通的Stack使用(数据类型为固定 Item 类型):
    Stack val_nomal;

  • 一个类模板Stack使用(增加类型指定,同一套代码,可以多个类型使用):
    Stack val1;
    Stack val2;

  • 类模板的声明和定义需要一一对应,因此 每个方法的定义,都附上了Type 类型。

  • Type 的值为 数据类型(泛型名), 因此也叫类型参数。

数组模板 和 非类型参数
  • 模拟array
    ArrayTP.h
template <typename T, int n>
class ArrayTP //array template
{
private:
	T ar[n];
public:
	ArrayTP() {};
	explicit ArrayTP(const T & v);
	virtual T & operator[](int i);
	virtual T operator[](int i)const;
}

ArrayTP.cpp

template <typename T, int n>
ArrayTP<T,n>::ArrayTP(const T &v)
{
	for(int i = 0; i < n; i++)
	{
		ar[i] = v;
	}
}

template <typename T, int n>
T & ArrayTP<T,n>::operator[](int i)
{
	if(i <0 || i >= n)
	{
		std::cerr << "Error in array limits: " << i << "is out of range\n";
		std::exit[EXIT_FALLURE];
	}
		return ar[i];
}
template <typename T, int n>
T ArrayTP<T,n>::operator[](int i) const
{
	if(i <0 || i >= n)
	{
		std::cerr << "Error in array limits: " << i << "is out of range\n";
		std::exit[EXIT_FALLURE];
	}
		return ar[i];
}
  • 数组模板,ArrayTP为数组功能,第二参数 int n 为数组长度。
  • 非类型参数,第二参数固定为int, 所以只能输入数值,而不能输入数据类型,称为非类型参数。
  • 使用上:
    ArrayTP<double, 10> array_val;
  • 缺陷:模板,会被具体化, 因此,不同参数就会生成不同的类。
    比如 ArrayTP<double 12>和ArrayTP<double 10>,编译器会生成两个类。
    并且,n 的值不能够被改变,也不能使用其地址。
模板的多功能性
1递归使用模板
  • ArrayTP<ArrayTP<int ,5> , 10 > twodee;
    那上述相当于:int twodee[10][5]
2使用多个类型参数

template <typename T1, typename T2>
class Topo{ … }

3默认类型模板参数

template <typename T1, typename T2 = int>
class Topo{ … }

  • 如果省略T2的值,编译器将使用int
模板的具体化
1隐式实例化
  • 上面那些直接用的就是隐式实例化
2显示实例化
  • template class ArrayTP<string, 100>;
    上述语句,可以在声明和定义之后,进行显示的实例化。
3显示具体化(对模板的一个指定的数据类型,做指定的处理)
  • 显示具体化是特定类型的定义,有时候,可能需要在为特殊类型实例化时,对模进行修改,使其行为不同。
    基本模板定义:
    template
    class SortedArray
    {
    …//
    };

具体化模板定义格式:
template <> class Classname{ … }
template <> class SortedArray<const char *>

4部分具体化
  • template >typename T1> class Class_name<T1, int >
成员模板(模板可用作结构、类或模板类的成员)
将模板用作参数
模板类和友元
  • 1 模板类的非模板友元函数
  • 2 模板类的约束模板友元函数
  • 3 模板类的非约束模板友元函数
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值