1.函数调用运算符
1、圆括号()就是函数调用的明显标记,()有一个称呼叫做“函数调用运算符”;
2、如果我在类中重载了函数调用运算符,那么我们就可以像使用函数一样使用该类的对象了。对象(实参):
使用:
a)定义一个该类的对象
b)像函数调用一样使用该对象,也就是()中增加实参列表
#include <iostream>
using namespace std;
class A
{
public:
A(int)
{
cout <<"构造函数" << endl;
}
//重载圆括号(函数调用运算符)
//可以有多个重载的类型
int operator()(int value) const
{
cout <<"重载函数运算符被调用了" <<endl;
if(value < 0) return 0;
return value;
}
};
int main()
{
int i = 100;
A a(2);//含有函数调用运算符的对象
int result = a(i);//等价于a.operator()(i);
//int result = a.operator()(i);
//构造函数,和 函数调用运算符的区别
A b(9);//这是调用了构造函数,定义对象并初始化
b(0);//这是对象的函数调用运算符
}
结论:
1)只要这个对象所属的类重载了()(函数调用运算符),那么这个类对象就变成了可调用的勒,而且可以调用多个版本的(),只要在参数类型或者数量上有差别即可;
class BiggerThanZero
{
public:
//重载圆括号(函数调用运算符)
BiggerThanZero(int i){};//有参构造函数
int operator()(int value) const //重载() 1
{
if (value < 0)
return 0;
return value;
}
int operator()(int value, char c) const//重载() 2
{
if (value < 0)
return 0;
return value;
}
int operator()(int value, char c, int value1) const//重载() 3
{
if (c < 0)
return 0;
return c;
}
};
2.不同调用对象的相同调用形式
class BiggerThanZero
{
public:
int operator()(int value) const
{
cout << "class value : " << value << endl;
if(value < 0)
return 0;
return value;
}
};
int echoValue(int value)//调用参数和返回值与BiggerThanZero类中的operator()成员相同
{
cout << "echoValue : " << value << endl;
if(value < 0)
return 0;
return value;
}
1)函数echoValue和类BiggerThanZero的重载(),这两个东西的调用参数和返回值相同,我们可以称之为“调用形式相同”;
2)一种调用形式对应一个函数类型,如int(int) 表示接受一个int参数和返回一个int值;
可调用对象
1.把这些可调用对象的指针保存下来,目的是方便调用这些“可调用对象”
int(*p) (int x);
p = echovalue;
int result = (*p) (5);
2.//用map,在里面放键值对:C++ STL 中 map 容器的说明和使用技巧
map<string ,int(*)(int)>myoper;
myoper.insert({"en",echovalue});//放键值对
A obj(2);//含有函数对象运算符
//myoper.insert({"bt",A});
//myoper.insert({"bt",obj});//都不可以 系统不认为这是函数指针,接着看下面的
3. 标准库function类型介绍
function类模板,要提供模板参数来表示该function;类型能够表示的"对象的调用形式"
function<int <int>> :接收一个int 返回一个int
1、function是一个类模板,头文件#include <functional>;
2、function类模板,要提供模板参数来表示该function类型能够表示的“对象的调用形式”,类模板std :: function是一个通用的多态函数包装器, std :: function的实例可以存储,复制和调用任何可调用的目标 :包括函数,lambda表达式,绑定表达式或其他函数对象,以及指向成员函数和指向数据成员的指针。当std::function对象未包裹任何实际的可调用元素,调用该std::function对象将抛出std::bad_function_call异常;
template< class R, class... Args >
class function<R(Args...)>;
模板参数说明:
R: 被调用函数的返回类型
Args…:被调用函数的形参
function<int(int)>//声明了一个function()类型,用来代表一个可调用对象,它所代表的这个可调
//用对象是:接受一个int参数,返回一个int类型;
A obj(2);//含有函数对象运算符
function<int (int)> f1 = echovalue;//函数指针
function<int (int)> f2 = obj;//类对象,类中有()重载
function<int (int)> f3 = A(2);//用类名生成一个对象。
#include <iostream>
#include <map>
#include <functional>
using namespace std;
class A
{
public:
A(int)
{
cout <<"构造函数" << endl;
}
//重载圆括号(函数调用运算符)
//可以有多个重载的类型
int operator()(int value) const
{
if(value < 0) return 0;
return value;
}
};
//普通函数
int echovalue(int value)
{
cout << value <<endl;
return value;
}
int main()
{
A obj(2);
function < int (int) > f1 = echovalue;
function < int (int) > f2 = obj;
function < int (int) > f3 = A(2);
cout << f1(2) <<endl;
cout << f2(66) <<endl;
cout << f3(-2) <<endl;
}
可调用对象的使用
class BiggerThanZero
{
public:
int operator=(int value) const
{
cout << "class value : " << value << endl;
if(value < 0)
return 0;
return value;
}
};
int echoValue(int value)//调用参数和返回值与BiggerThanZero类中的operator()成员相同
{
cout << "echoValue : " << value << endl;
if(value < 0)
return 0;
return value;
}
int main()
{
map<string, function<int(int)>> myoper = {
{"a1", echoValue},
{"a2", obj},
{"a3", BiggerThanZero}
};
myoper["a1"](12);//调用echoValue函数
myoper["a2"](13);//调用obj对象的operator()函数
myoper["a3"](14);//调用BiggerThanZero类重载()函数
return 0;
}
1、一旦function遇到echoValue的重载版本就无法识别,编译不通过;
int echoValue(int value)//调用参数和返回值与BiggerThanZero类中的operator()成员相同
{
cout << "echoValue : " << value << endl;
if(value < 0)
return 0;
return value;
}
int echoValue()
{
return 1;
}
int main()
{
map<string, function<int(int)>> myoper = {
{"a1", echoValue};//编译报错
};
return 0;
}
解决:我们可以通过定义函数指针类解决,如下:
int (*fp)(int) = echoValue;
int (*fp1)() = echoValue;
#include <iostream>
#include <map>
#include <functional>
using namespace std;
class A
{
public:
A(int)
{
cout <<"构造函数" << endl;
}
int operator()(int value) const
{
if(value < 0) return 0;
return value;
}
};
//普通函数
int echovalue(int value)
{
cout << value <<endl;
return value;
}
//函数 重载的话就会失败
int echovalue()
{
return 1;
}
int main()
{
A obj(2)
//解决:
//可以通过定义函数指针来解决
int(*p)(int) = echovalue ;
int(*p2)() = echovalue ;
function<int()> f2 = p2;
function<int(int)> f1 = p;
}