operator

更新时间:2022-12-30 15:11:08 阅读: 评论:0


2022年12月30日发(作者:埃琳娜 吉尔伯特)

C++operator()(重载⼩括号运算符)

分类专栏:C++总结重载⼩括号运算符⽂章标签:operator()重载⼩括号运算符仿函数

版权

在C++语⾔中有时候需要重载运算符:(),今天我们主要介绍它主要应⽤的场合。

仿函数

先考虑⼀个简单的例⼦:假设有⼀个vector,你的任务是统计长度⼩于5的string的个数,如果使⽤count_if函数的话,你的代码可能长成

这样:

其中count_if函数的第三个参数是⼀个函数指针,返回⼀个bool类型的值。⼀般的,如果需要将特定的阈值长度也传⼊的话,我们可能将函

数写成这样:

这个函数看起来⽐前⾯⼀个版本更具有⼀般性,但是他不能满⾜count_if函数的参数要求:count_if要求的是unaryfunction(仅带有⼀个

参数)作为它的最后⼀个参数。所以问题来了,怎么样找到以上两个函数的⼀个折中的解决⽅案呢?

这个问题其实可以归结于⼀个dataflow的问题,要设计这样⼀个函数,使其能够access这个特定的length值,回顾我们已有的知识,有2

种解决⽅案可以考虑:

函数的参数:

这种⽅法我们已经讨论过了,多个参数不适⽤于count_if函数;

全局变量:

我们可以将长度阈值设置成⼀个全局变量,代码可能像这样:

这段代码看似很不错,实则不符合规范,刚重要的是,它不优雅。原因有以下⼏点要考虑:

容易出错:

为什么这么说呢,我们必须先初始化maxLength的值,才能继续接下来的⼯作,如果我们忘了,则可能⽆法得到正确答案。此外,变量

maxLength和函数LengthIsLessThan之间是没有必然联系的,编译器⽆法确定在调⽤该函数前是否将变量初始化,给码农平添负担;

没有可拓展性:

如果我们每遇到⼀个类似的问题就新建⼀个全局变量,尤其是多⼈合作写代码时,很容易引起命名空间污染(namespacepolution)的问

题;当范围域内有多个变量时,我们⽤到的可能不是我们想要的那个;

全局变量的问题:

每当新建⼀个全局变量,即使是为了coding的便利,我们也要知道我们应该尽可能的少使⽤全局变量,因为它的cost很⾼;⽽且可能暗⽰

你这⾥有⼀些待解决的优化⽅案。

说了这么多,还是要回到我们原始的那个问题,有什么解决⽅案呢?答案当然就是这篇⽂章的主题部分:仿函数。我们的初衷是想设计⼀个

unaryfunction,使其能做binaryfunction的⼯作,这看起来并不容易,但是仿函数能解决这个问题。

1boolLengthIsLessThanFive(conststring&str){

()<5;

3}

4intres=std::count_if((),(),LengthIsLessThanFive);

1boolLenthIsLessThan(conststring&str,intlen){

()

3}

1intmaxLength;

2boolLengthIsLessThan(conststring&str){

()

4}

5intres=std::count_if((),(),LengthIsLessThan);

先来看仿函数的通俗定义:仿函数(functor)⼜称为函数对象(functionobject)是⼀个能⾏使函数功能的类。仿函数的语法⼏乎和我们

普通的函数调⽤⼀样,不过作为仿函数的类,都必须重载operator()运算符,举个例⼦:

仿函数其实是上述解决⽅案中的第3种⽅案:成员变量。成员函数可以很⾃然的访问成员变量:

我相信这个例⼦能让你体会到⼀点点仿函数的作⽤了;它既能想普通函数⼀样传⼊给定数量的参数,还能存储或者处理更多我们需要的有⽤

信息。

让我们回到count_if的问题中去,是不是觉得问题变得豁然开朗了?

count_if((),(),ShorterThan(length));//直接调⽤即可

这⾥需要注意的是,不要纠结于语法问题:ShorterThan(length)似乎并没有调⽤operator()函数?其实它调⽤了,创建了⼀个临时对象。

你也可以⾃⼰加⼀些输出语句看⼀看。

1classFunc{

2public:

3voidoperator()(conststring&str)const{

4cout<

5}

6};

7FuncmyFunc;

8myFunc("helloworld!");

9output:helloworld!

1classStringAppend{

2public:

3explicitStringAppend(conststring&str):ss(str){}

4

5voidoperator()(conststring&str)const{

6cout<

7}

8

9private:

10conststringss;

11};

12

13StringAppendmyFunc("isworld");

14myFunc("hello");

15output:helloisworld

1classShorterThan{

2public:

3explicitShorterThan(intmaxLength):length(maxLength){}

4booloperator()(conststring&str)const{

()

6}

7private:

8constintlength;

9};

类型转换

C++中可以定义类型转换函数,将类对象转换为其他类型,函数原型为:operatorType()类型转换函数与转换构造函数具有同等的地位;

类型转换函数使得编译器有能⼒将对象转化为其他类型;

编译器能够隐式的使⽤类型转换函数;

转换为普通数据类型

1#include

2#include

3usingnamespacestd;

4classTest

5{

6

7public:

8Test(inti=0)

9{

10mValue=i;

11}

12intvalue()

13{

14returnmValue;

15}

16operatorint()

17{

18returnmValue;

19}

20

21private:

22intmValue;

23};

24

25intmain()

26{

27Testt(100);

28inti=t;

29

30cout<<"()="<<()<

31cout<<"i="<

32

33return0;

34}

35

36类类型之间的转换

37#include

38#include

39

40classTest;

41

42classValue

43{

44public:

45Value()

46{

47

48}

49

50Value(Test&t)//fal

51//explicitValue(Test&t)//Ok

52{

53std::cout<<"explicitValue(Test&t)"<

54}

55};

56

57classTest

从输出结果我们可以发现:转换构造函数和类型转换函数发⽣冲突了,编译器不知道应该调⽤哪个函数。因此发⽣了错误。

当然我们可以使⽤explicit关键字抑制隐式的转换构造函数,让程序只调⽤类型转换函数。但是,我们⽆法抑制隐式的类型转换函数。

57classTest

58{

59intmValue;

60

61public:

62Test(inti=0)

63{

64mValue=i;

65}

66

67intvalue()

68{

69returnmValue;

70}

71

72operatorValue()

73{

74Valueret;

75std::cout<<"operatorValue()"<

76returnret;

77}

78};

79

80intmain()

81{

82Testt(100);

83Valuev=t;

84

85return0;

86}

本文发布于:2022-12-30 15:11:08,感谢您对本站的认可!

本文链接:http://www.wtabcd.cn/fanwen/fan/90/60518.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

上一篇:who
下一篇:汨罗江社区
标签:operator
相关文章
留言与评论(共有 0 条评论)
   
验证码:
Copyright ©2019-2022 Comsenz Inc.Powered by © 专利检索| 网站地图