9-1函数调用运算符()、不同调用对象的相同调用形式、可调用对象、 标准库function(c++11)

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;
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值