开发者社区> hopegrace> 正文
阿里云
为了无法计算的价值
打开APP
阿里云APP内打开

21、C++ Primer 4th 笔记,重载运算符(2)

简介: 1、自增操作符和自减操作符 为了与内置类型一致,前缀操作符应返回被增量或减量对象的引用;后辍式操作符应返回旧值(不是引用)。后辍式操作符函数接受一个额外的(即无用的)int型形参。 示例 #include "iostream" #include "stdio.
+关注继续查看

1、自增操作符和自减操作符

为了与内置类型一致,前缀操作符应返回被增量或减量对象的引用;后辍式操作符应返回旧值(不是引用)。后辍式操作符函数接受一个额外的(即无用的)int型形参。

示例

#include "iostream"
#include "stdio.h"
using namespace std;

class CheckedPtr
{
public:
	CheckedPtr(int *b, int *e):beg(b), end(e), curr(e){}
public:
	CheckedPtr& operator++();  //前辍
	CheckedPtr& operator--();
	CheckedPtr  operator++(int);//后辍
	CheckedPtr  operator--(int);
private:
	int *beg;
	int *end;
	int *curr;
};

CheckedPtr& CheckedPtr::operator++()
{
	if (curr == end)
		throw out_of_range("increment past the end of CheckedPtr");
	++curr;
	return *this;
}
CheckedPtr& CheckedPtr::operator--()
{
	if (curr == beg)
		throw out_of_range("decrement past the beginning of CheckedPtr");
	--curr;
	return *this;
}

CheckedPtr CheckedPtr::operator++(int)
{
	CheckedPtr ret(*this);
	++*this; //调用前辍增量操作符,在本函数中无需作越界检查
	return ret;
}
CheckedPtr CheckedPtr::operator--(int)
{
	CheckedPtr ret(*this);
	--*this; //调用前辍减量操作符,在本函数中无需作越界检查
	return ret;
}
int main()
{
	CheckedPtr parr(ia, ia + size);
	parr.operator++(0); //显式调用后辍增量操作符
	parr.operator++();  //显式调用前辍增量操作符
	return 0;
}

显式调用操作符

示例如上中。

所传递的值通常会被忽略,便是必要的。

2、函数调用操作符和函数对象

可以为类类型的对象重载函数调用操作符。一般表示操作的类重载调用操作符。函数调用操作符必须声明为成员函数,可以重载(由形参的数目或类别加以区别)。

示例

#include "iostream"
#include "stdio.h"
using namespace std;

struct absInt
{
	int operator()(int val)
	{
		return val < 0 ? -val:val;
	}
};

int main()
{
	int i = -42;
	absInt absOjb;
	unsigned int ui = absOjb(i);
	return 0;
}

通过为类类型的对象提供一个实参表而使用调用操作符,看起来像一个函数调用。定义了函数调用操作符的类,其对象常称为函数对象,即他们是行为类似函数的对象。

3、将函数对象用于标准库算法

使用谓词函数示例

#include "iostream"
#include "stdio.h"
using namespace std;

bool GT6(const string &s)
{
	return s.size() >= 6;
}

int main()
{
	vector<string>::size_type wc = count_if(words.begin(), words.end(), GT6)
	return 0;
}

使用函数对象比使用谓词函数更灵活。

函数对象示例

#include "iostream"
#include "stdio.h"
#include "algorithm"
#include "functional"
using namespace std;

class GT_cls
{
public:
	GT_cls(size_t val = 0):bound(val){}
	bool operator()(const string &s)
	{
		return s.size() >= bound;
	}
private:
	std::string::size_type bound;
};

int main()
{
	vector<string> words;
	vector<string>::size_type wc = count_if(words.begin(), words.end(), GT_cls(6));
	return 0;
}

4、标准库定义的函数对象

这些标准库函数对象类型放在functional头文件中定义。

算术函数对象类型

函数对象

所应用的操作符

plus<Type>

applies +

minus<Type>

applies -

multiplies<Type>

applies *

divides<Type>

applies /

modulus<Type>

applies %

negate<Type>

applies -

关系函数对象类型

equal_to<Type>

applies ==

not_equal_to<Type>

applies !=

greater<Type>

applies >

greater_equal<Type>

applies >=

less<Type>

applies <

less_equal<Type>

applies <=

逻辑函数对象类型

logical_and<Type>

applies &&

logical_or<Type>

applies |

logical_not<Type>

applies !

    有两个一元函数对象类:一元减(negate<Type>))和逻辑非(logical_not<Type>))。其余的标准库函数对象都是表示二元操作符的二元函数对象类。为二元操作符定义的函数调用操作符需要两个给定类型的形参,而一元函数对象类型定义了接受一个实参的调用操作符。

示例

#include "iostream"
#include "vector"
#include "algorithm"
#include "string"
#include "functional"
using namespace std;

class GT_cls
{
public:
	GT_cls(size_t val = 0):bound(val){}
	bool operator()(const string &s)
	{
		return s.size() >= bound;
	}
private:
	std::string::size_type bound;
};

int main()
{
	plus<int> intAdd;
	int sum = intAdd(10, 20);
	vector<string> svec;
	sort(svec.begin(), svec.end(), greater<string>() );
	cout << sum;
}

5、函数对象的函数适配器

    标准库提供了一组函数适配器,用于特化和扩展一元和二元函数对象。函数适配器分为如下两类:

1)绑定器,是一种函数适配器,它通过将一个操作数绑定到给定值而将二元函数对象转换为一元函数对象。

2)求反器,是一种函数适配器,它将谓词函数对象的真值求反

标准库定义了两个绑定器适配器:bind1st bind2nd。每个绑定器接受一个函数对象和一个值。bind1st 将给定值绑定到二元函数对象的第一个实参,bind2nd 将给定值绑定到二元函数对象的第二个实参。

标准库还定义了两个求反器:not1 not2not1 将一元函数对象的真值求反,not2 将二元函数对象的真值求反。

示例

count_if(vec.begin(), vec.end(), bind2nd(less_equal<int>(), 10));
count_if(vec.begin(), vec.end(), not1(bind2nd(less_equal<int>(), 10)));

#include "iostream" 

#include "stdio.h" 

using namespace std;

struct absInt

{

int operator()(int val)

{

return val < 0 ? -val:val;

}

};

int main()

{

int i = -42;

absInt absOjb;

unsigned int ui = absOjb(i);

return 0;

}

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
【C++初阶:STL —— string】string类 | 浅拷贝和深拷贝(传统写法和现代写法) | string类的模拟实现 上
【C++初阶:STL —— string】string类 | 浅拷贝和深拷贝(传统写法和现代写法) | string类的模拟实现
44 0
【C++初阶:STL —— vector】vector的介绍及使用 | 迭代器失效问题 | vector的深度剖析及模拟实现 上
【C++初阶:STL —— vector】vector的介绍及使用 | 迭代器失效问题 | vector的深度剖析及模拟实现
78 0
【C++初阶:STL —— vector】vector的介绍及使用 | 迭代器失效问题 | vector的深度剖析及模拟实现 下
【C++初阶:STL —— vector】vector的介绍及使用 | 迭代器失效问题 | vector的深度剖析及模拟实现
54 0
【C++初阶:STL —— list】list的介绍及使用 | list的深度剖析及模拟实现 | list与vector的对比 上
【C++初阶:STL —— list】list的介绍及使用 | list的深度剖析及模拟实现 | list与vector的对比
27 0
【C++初阶:STL —— list】list的介绍及使用 | list的深度剖析及模拟实现 | list与vector的对比 下
【C++初阶:STL —— list】list的介绍及使用 | list的深度剖析及模拟实现 | list与vector的对比
31 0
【C++初阶:STL —— stack and queue】stack/queue的介绍及使用 | stack/queue/priority_queue的深度剖析及模拟实现 | 适配器模式 | 仿函数 上
【C++初阶:STL —— stack and queue】stack/queue的介绍及使用 | stack/queue/priority_queue的深度剖析及模拟实现 | 适配器模式 | 仿函数
26 0
【C++初阶:STL —— stack and queue】stack/queue的介绍及使用 | stack/queue/priority_queue的深度剖析及模拟实现 | 适配器模式 | 仿函数 下
【C++初阶:STL —— stack and queue】stack/queue的介绍及使用 | stack/queue/priority_queue的深度剖析及模拟实现 | 适配器模式 | 仿函数
33 0
利用C/C++扩展php语言实现 Usher_GetHostIP无参函数
PHP程序员需要略会C也是必要的,不管从业务角度还是 专业角度,因为C是PHP的母语。并且我们一般不会用原生PHP来处理大批量业务逻辑,这个时候我们需要扩展, 。 PHP从语言本质来说的确是一门不错的语言,如果灵活的运用,他不应该成为阻碍我们前进的瓶颈,反而是一把利器。
968 0
简单RTP发送类c++实现
我之前编译了jrtplib 3.9.1,并且在项目中使用,结果发现在用这个库时,程序体积有增加了300多K,感觉实在是有点笨重,我无法就是用来发送rtp包而已。想想还是自己重新实现一个简单的类用用拉倒了,所以有了下面的代码。
1186 0
C++ - 多线程的实现
  支持多线程可谓是C++语言最大的变化之一. 此前,C++只能利用操作系统的功能(Unix族系统使用pthreads库),或是例如OpenMP和MPI这些代码库,来实现多核计算的目标. C++本身并没有提供任何多线程机制,但是在windows下,我们可以调用SDK win32 api来...
713 0
+关注
698
文章
0
问答
文章排行榜
最热
最新
相关电子书
更多
低代码开发师(初级)实战教程
立即下载
阿里巴巴DevOps 最佳实践手册
立即下载
冬季实战营第三期:MySQL数据库进阶实战
立即下载