首页 > 学院 > 开发设计 > 正文

函数调用运算符与重载、类型转换

2019-11-14 09:52:30
字体:
来源:转载
供稿:网友

函数调用运算符Operator() 函数运算符必须是成员函数。一个类可以定义多个不同版本的调用运算符,相互之间应该在参数数量或类型上有所区别。如果类定义了调用运算符,则该类的对象称作函数对象。 函数对象类除了operator之外还可以包含其他成员。这些成员通常用于定制调用运算符中的操作。

#include <iostream>#include <string>class A{public: int operator()(bool a,int b,int c) const { if(a) return b; else return c; }};class GetInput{public: GetInput(std::istream &i=std::cin):is(i){} std::string operator()()const { std::string str; std::getline(is,str); return is?str:std::string(); }PRivate: std::istream &is;};int main(){ A a; int ret=a(0,7,8); std::cout<<ret<<std::endl; GetInput gi; std::cout<<gi()<<std::endl; return 0;}

lambda表达式相当于一个类含有函数调用符的对象。

stable_sort(Words.begin(),words.end(),[](const string &a,const string &b){return a.size()<b.size()});等价于class shorterstring{public: bool operator()(const string &a,const string &b) const { return a.size()<b.size() }}

标准库定义了一组表示算术运算符、关系运算符和逻辑运算符的类。这些类被定义成模板的形式。

这里写图片描述

#include <iostream>#include <functional>int main(){ std::plus<int> intadd; int sum=intadd(10,20); std::cout<<sum; return 0;}

C++语言有几种可调用的对象:函数,函数指针,lambda表达式,bind创建的对象,重载的函数运算符的类。不同类型可能有相同的调用形式。在制作函数表的时候,我们可以利用function模板来实现不同类型而具有相同调用形式形成函数表。

#include <functional>#include <iostream>#include <map>#include <string>int add(int i,int j){return i+j;}auto mod=[](int i,int j){return i%j;}; struct Div{ int operator ()(int i, int j) const { return i / j; } };auto binops=std::map<std::string,std::function<int(int,int)>>{ {"+",add},//加法,函数指针 {"%",mod},//求余,命名的lambda对象 {"/",Div()},//除法,函数对象类 {"-" ,std::minus<int>()},//减法,标准库函数对象 {"*",[](int i,int j){return i*j;}}//乘法,未命名的lambda对象 };int main(){ while ( std::cout << "Pls enter as: num operator num :/n", true ) { int lhs, rhs; std::string op; std::cin >> lhs >> op >> rhs; std::cout << binops[op](lhs, rhs) << std::endl; } return 0;}

类型转换运算符是类的一种特殊的成员函数,它负责将一个类类型的值转换成其他类型。一个类型转换函数必须是类的成员函数,它不能声明返回类型,形参列表也必须为空。类转换类型函数通常是const.

operator type() const;

类型转换运算符可能产生意外的结果,C++11新标准引入了显示的类型转换运算符

class SmallInt{ explicit operator int() const{return val;}}SmallInt si=3;//正确si+3;//错误,需要隐式类型转换,但类运算符是显式的static_cast<int>(si)+3;//正确:显式地请求类型转换

向bool的类型转换通常用在条件部分,因此operator bool一般定义成explicit.


如果类中包含一个或多个类型,则必须确保在类类型和目标类型之间只存在唯一一种转换方式。 (1)实参匹配和相同的类型转换

struct B;struct A{ A()=default; A(const B&);};struct B{ operator A() const; };A f(const A&);B b;A a=f(b);//二义性错误:f(B::operator A()) ?f(A::A(const B&))A a1=f(b.operator A());//正确:使用B的类型转换运算符A a2=f(A(b));//正确:使用A的构造函数

(2)二义性与转换目标为内置类型的多重类型转换

这里写图片描述


发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表