【C++】类模板(二)类模板、函数模板、常量表达式与默认参数值、模板参数设计策略、成员模板函数

实现一个类模板

格式:

template<typename 占位符>

(inline) 返回类型 模板类类名<自定义类型名>::
模板类成员函数名(const 自定义类型名 &参数名)

一个以函数模板完成的<<运算符

//非模板函数形式
ostream& operator<<(ostream&,const BinaryTree<int>& );

//模板函数形式
template <typename elemType>
inline ostream&
operator<<( ostream &os,const BinaryTree<elemType>&bt)
{
	os << "Tree:" << endl;
	bt.print(os);
	return os;
}


BinaryTree<string>bts;
cout<<bts<<endl;
//编译器将elemType指定为string,产生一个对应的<<运算符

BinaryTree<int>bti;
cout<<bti<<endl;
//编译器将elemType指定为int,产生一个对应的<<运算符

常量表达式与默认参数值

也可以用常量表达式作为模板参数:

template<int len,int beg_pos>

class num_sequence
{
public:
	virtual ~num_sequence(){};
	
	int elem(int pos)const;
	const char* what_am_i()const;
	static int max_elems(){return _max_elems;}
	
	ostream& print(ostream &os=cout) const;
	
protected:
	virtual void gen_elems(int pos) const = 0;
	
	bool check_integrity(int pos,int size)const;
	num_sequence(vector<int>*pe):_pelems(pe){}
	static const int _max_elems = 1024;
	vector<int> *_pelems;
};
template<int length, int beg_pos = 1>//带有默认参数值
class Fibonacci:public num_seuqence<length,beg_pos>
{
public:
	Fibonacci():num_sequence<length,beg_pos>(&_elems){}
	
protected:
	virtual void gen_elems(int pos)const;
	static vector<int> _elems;
};

全局作用域内的函数和对象,其地址也是一种常量表达式,因此可以用来表达模板参数:

template<void (*pf)(int pos, vector<int> &seq)>

class numeric_sequence
{
public:
	numeric_sequence(int len,int beg_pos = 1)
	{
		if(!pf)//....产生错误信息并退出
		{...}
		
private:
	int _len;
	int _beg_pos;
	vector<int> _elems;
};

//使用
//pf指向“依据特定数列类型,产生pos个元素,放到vector seq内”的函数
void fibonacci(int pos,vector<int>&seq);
void pell(int pos,vector<int>&seq);
//...
numeric_seuqence<fibonacci> ns_fib(12);
numeric_seuqnece<pell> ns_peel(18,8);

以模板参数作为一种设计策略

将某种特定的命名规范强加于被当作参数的类身上:每个类都必须提供类模板中调用到的函数。

template<typename num_seq>
class NumericSequence{
public:
	NumericSequence(int len=1,int bpos=1):_ns(len,bpos){}
	//以下会通过函数的命名规范,调用未知的数列类中的同名函数
	//此处所谓函数命名规范是:每个num_seq参数类都必须提供
	//名为calc_elems和is_elem的函数
	void calc_elems(int sz) const {_ns.calc_elems(sz);}
	bool is_elem(int elem) const {return _ns.is_elem(elem);}
	//...
	
private:
	num_seq _ns;
};

成员模板函数

非模板类里定义成员模板函数:
在只写一份函数定义的情形下,支持任何类型。

class PrintIt
{
public:
	PrintIt(ostream &os):_os(os){}
	
//成员模板函数
template<typename elemType>
void print(const elemType &elem,char delimiter='\n')
{
	_os << elem << delimiter;
}
private:
	ostream &os;
}

模板类里定义成员模板函数:

template<typename OutStream>
class PrintIt{
public:
	PrintIt(OutStream &os):_os(os){}
	
	//成员模板函数
	template <typename elemType>
	void print(const elemType &elem,char delimiter='\n')
	{
		_os<<elem<<delimiter;
	}
private:
	ostream& _os;
};
  • 4
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值