1)//函数对象包装器:就是相当于把函数也封装成容器使用;
//支持4种函数的封装:普通函数,成员函数,匿名函数,仿函数
#include <iostream>
#include <string>
#include <map>
#include <functional>
int test(int n) //普通函数
{std::cout<<"n is:"<<n<<std::endl;return 4;
}
class People
{
public:People(){}int MyPeople(int n) //成员函数{std::cout<<"people is:"<<n<<std::endl;return 0;}
};class Sort
{
public:int operator()(int n){std::cout<<"sort is:"<<n<<std::endl; return 0;}
};int main()
{std::function<int(int)> f1 = test;f1(3);std::function<int(People*,int)> f2 = &People::MyPeople;People p1;f2(&p1,33);std::function<int(Sort*,int)> f3 = &Sort::operator();Sort s1;f3(&s1,444);std::function<int(int)> f4 = [](int n)->int{ std::cout<<"lambda number is:"<<n<<std::endl; return 0;};f4(5);return 0;
}
- 移动构造函数,注意右值的使用,代码如下:
#include <iostream>
#include <string>
#include <map>
#include <functional>
#include <vector>
using namespace std;class Move
{
public:int a_;Move(int a) : a_(a){cout<<"in constructor"<<a<<endl;}Move(const Move& move){cout<<"copy constructor"<<move.a_<<endl;}// move constructorMove(Move&& move) noexcept //不要抛异常{cout<<"in move constructor"<<move.a_<<endl;this->a_ = move.a_;}~Move(){cout<<"in destructor"<<endl;}
};int main(void)
{vector<Move> vec;vec.push_back(Move{10});return 0;
}
3)顶层const和底层const的函数重载
//把鼠标放到func函数上,会提示void func(int* a)
void func(int* const a){ } //与下面是统一函数(const 可以去掉),所以重载失败
void func(int* a) {}
4)类内重载加号+运算符和类外重载加号+运算符的案例1:
#include <iostream>
using namespace std;class A
{
public:A(int a) : a_(a){}A(void) : a_(0){}//默认构造friend A operator+(const A& lhs,const A& rhs); //不用声明也可以编译通过A& operator+(const A& a){cout<<"in operator+"<<a.a_<<endl;this->a_ += a.a_;return *this;}int a_;
};A operator+(const A& lhs,const A& rhs)
{A a;cout<<"gengral operator+"<<endl;a.a_ = lhs.a_ + rhs.a_;return a;
}int main(void)
{A a1(1);A a2(2); A a3 = a1 + a2; //binary operand 二元运算,优先选择类内的运算符重载,如果没有,则到类外找(name lookup)cout<<"a1: "<<a1.a_<<endl; cout<<"a2: "<<a2.a_<<endl; cout<<"a3: "<<a3.a_<<endl; return 0;
}
5)运算符operator<<函数的使用(输出运算符重载)
#include <iostream>
#include<ostream>
using namespace std;class A
{
public:int num;A(int a) : num(a){}friend ostream& operator<<(ostream &out,const A& a); //这个friend必须得写
};ostream& operator<<(ostream &out,const A& a)
{out<<"in operator<<: "<<a.num<<endl;return out;
}int main(void)
{A a1(3);cout<<a1<<endl;return 0;
}
6)关系运算符重载operator==,operator!=的使用案例:
#include <iostream>
#include<map>using namespace std;class A
{
public:A(int a) : a_(a){}bool operator==(const A& a2){ cout<<"in operator== "<<endl; return this->a_ == a2.a_; }bool operator!=(const A& a2){ cout<<"in operator!= "<<endl; return !(*this == a2); } //把工作交给另外一个成员函数去做 int a_;
};int main(void)
{A a1(1);A a2(1);cout<<(a1 != a2)<<endl;return 0;
}//输出结果:
in operator!=
in operator==
0
7)赋值运算符重载案例:(赋值运算符必须是成员函数):
#include <iostream>
#include<initializer_list>
#include<vector>using namespace std;class A
{
public:vector<int> vec;A& operator=(std::initializer_list<int> list){for(const int& num : list) {vec.push_back(num);}return *this;}
};int main(void)
{A a;a = {1,2,3,4};cout<<a.vec.back()<<endl;return 0;
}
8)下标运算符重载案例:
#include <iostream>
#include<initializer_list>
#include<vector>using namespace std;class A
{
public:vector<int> vec = {2,3};A& operator=(std::initializer_list<int> list){for(const int& e: list){vec.push_back(e);}return *this;}int& operator[](std::size_t index) //operator[]下标运算符重载{cout<<"in operator[] "<<endl;return vec[index];}//const主要用于带有const对象案例const int& operator[](std::size_t index) const //如果定义了非const的,则也需要定义const的{cout<<"in const operator[]"<<endl;return vec[index];}
};
int main(void)
{A a1;a1 = {1,2,3};cout<<a1[0]<<endl;const A a2; cout<<a2.operator[](0)<<endl;cout<<a2[0]<<endl;return 0;
}
9)前置++和后置++的运算符重载:
#include <iostream>
#include<initializer_list>
#include<vector>using namespace std;class Point
{
public:int x_;int y_;Point(int x,int y) : x_(x),y_(y){}Point& operator++(void) //前置++{cout<<"prefix++"<<endl;this->x_++;this->y_++;return *this;}const Point operator++(int) //后置++{cout<<"postfix++"<<endl;Point tmp = *this;this->x_++;this->y_++;return tmp;} friend ostream& operator<<(ostream& out,const Point& p);
};ostream& operator<<(ostream& out,const Point& p)
{out<<"x:"<<p.x_<<" "<<"y:"<<p.y_<<endl;return out;
}
int main(void)
{Point p(2,2);cout<<++p<<endl; //输出3 3cout<<p++<<endl; //输出3 3后point变为4 4cout<<p<<endl; //输出4 4return 0;
}
10)-> arrow 运算符重载案例:(arrow ->: overload member access)案例:
#include <iostream>
#include<initializer_list>
#include<vector>using namespace std;class A
{
public:int* a_;A(int a) : a_(new int(a)){}~A(){delete a_;}void func(void){cout<<"class A func running"<<endl;}
};class Point
{
public:int x_;int y_;A* pa_;Point(int x,int y) : x_(x),y_(y),pa_(new A(x)){}A* operator->(void) //一定要返回指针{cout<<"in point"<<endl;return pa_;}
};
//通过->运算符重载,point可以触及到本不属于自己类的成员!!!
int main(void)
{Point point(2,2);point->func(); //等价于 point.operator->()->func();int* res = point->a_;cout<<"res: "<<(*res)<<endl;return 0;
}
- 重载小括号()运算符(函数对象)和lambda的案例:
#include <iostream>
#include<initializer_list>
#include<vector>using namespace std;class A
{
public:int a_;A(int a) : a_(a){}A& operator()(int a){this->a_ += a;return *this;}
};
//函数对象和lambda其实本质上是一样的!
int main(void)
{A a(4);a(5);cout<<a.a_<<endl; //输出9;auto ret = [](){ //一般都用auto接匿名函数return 2 + 2;};cout<<"ret: "<<ret()<<endl; //输出4return 0;
}