C++沉思录读书笔记(29章)- 应用器,操纵器和函数对象

我们经常在程序中看见诸如int n; cout<<n<<flush;

对于cout<<n这部分代码,我们很清楚其工作流程,这部分的实现是通过重载<<实现的,通过重载<<,可以输出不同类型的值,下面是一个重载<<输出类型Complex的例子

ostream& operator<<(ostream& file, const Complex& z)
{
	file << "(" << z.re() << "," << z.im() << ")";
	return file;
} 

对于cout << flush,实际上上这段代码等同于flush(cout),假设flush是一个函数指针(实际上它有可能是一个函数对象)的话,我们如何实现cout << flush等同于flush(cout)呢?
假设flush函数的定义如下:

ostream& flush(ostream &file)
{
	//funtion code
	return file;
}
其实同样通过重载<<,我们可以实现将cout << flush等同于flush(cout),这个重载<<形式如下:

ostream& operator<<(ostream& file, ostream& (*func)(osteam&))
{
	return (*func)(file);
}


操纵器带有参数的形式
假设有如下代码:

ostream& setSpeed(ostream& file, int n)
{
	//funtion code
	return file;
}
这个函数的作用是设置流的数据传输速率
我们如何设计包装使得cout << speed(9600)的作用等同于setSpeed(cout, 9600)呢?

C++沉思录给出了一种经典实现,代码如下:

class int_fcn_obj
{
public:
	int_fcn_obj(ostream& (*f)(ostream&, int), int v)
		:func(f), val(v) {}
	ostream& operator()(ostream& o) const
	{
		return (*func)(o, val);
	}
private:
	ostream& (*func)(ostream& int);
	int val;
};

ostream& operator<<(ostream& ofile, const int_fcn_obj& im)
{
	return im(ofile);
}

int_fcn_obj speed(int n)
{
	return int_fcn_obj(setSpeed, n);
}
C++沉思录作者将上述的speed和flush成为操纵器,把重载的<<称为应用器,针对每一个操纵器,我们可以定制对应的应用器和函数对象,但是实际上不同的<操纵器,应用器,函数对象>对的定义都很相似,所以可以将其提升为模板,上述代码对应的模板如下:

//函数对象模板
template <class stype, class vtype>
class fcn_obj
{
public:
	fcn_obj(stype& (*f)(stype&, vtype), vtype v)
		:func(f), val(v) {}
	stype& operator()(stype& o) const
	{
		return (*func)(o, val);
	}
private:
	stype& (*func)(stype& vtype);
	vtype val;
};

//应用器模板
template <class stype, class vtype>
stype& operator<<(stype& ofile, const fcn_obj<stype, vtype> & im)
{
	return im(ofile);
}

//一个操纵器的例子
fcn_obj<ostream, int> speed(int n)
{
	return fcn_obj(setSpeed, n);
}

//使用方法
cout << speed(9600);


这样的技巧大量的用在了C++库的编写之中,比如cout << "hello world" << endl这句代码就使用了叫做endl的操纵器和它相应的应用器。


总结:C++中的奇迹淫巧确实太多了!!!

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值