C++快速讲解(六):运算符重载和lambda表达式


前言:主要介绍了运算符重载和lambda的使用。


1.运算符简单使用

1.1 成员函数方式

把重载的运算符函数定义在类中,此时只需要接收一个参数,因为类的对象本身作为+ 的前面调用者。
实现自定义的加法:

#include <iostream>
//成员函数方式 把重载的运算符函数定义在类中,此时只需要接收一个参数,因为类的对象本身作为+ 的前面调用者。
using namespace std;

class DiyAdd{
public:
    int number;

    DiyAdd(int number):number{number}{
        cout<<"构造函数"<<endl;
    }

    //自定义两个数字之和
    //方便在外面接收
    DiyAdd operator+ (DiyAdd &n){
        DiyAdd temp(this->number+n.number);
        return temp;
    }
};
int main() {
    DiyAdd d1(10);
    DiyAdd d2(20);
    DiyAdd d3 = d1+d2;
    cout<<"d3:"<<d3.number<<endl;
    return 0;
}

在这里插入图片描述

1.2 全局函数方式

并不是所有的运算符重载都能定义在类中,比如,需要扩展一些已有的类,对它进行运算符重载,而这些类已经被打成了一个库来使用,此时通过全局函数的方式来实现运算符重载。

#include <iostream>
#include <string>
//全局函数方式

using namespace std;

class DiyAdd{

public:
    int number;

    DiyAdd(int number):number(number){
        cout<<"function"<<endl;
    }
};

//由于函数并非定义在类中,所以此处无法使用到this指针,则需要传递两个对象进来。
DiyAdd operator+ (DiyAdd &d , DiyAdd &dd ){
    DiyAdd temp(d.number + dd.number);
    return temp;
}

int main() {

    DiyAdd d1(20);
    DiyAdd d2(30);

    //这里等于使用s1的对象,调用了operator+这个函数, +后面的 s2 则被当成参数来传递
    DiyAdd d3 = d1 + d2;


    cout << "d3.number = " << d3.number << endl;
    return 0;
}

在这里插入图片描述

2.输出运算符重载

#include <iostream>
#include <string>
//输出运算符重载
using namespace std;

class Student{
public:
    string name = "zhangsan";
    Student(string name){
        this->name = name;
    }
};

//对 << 运算符进行重载。 这里使用的是全局函数 ,第一个参数ostream 是因为在外面调用<<这个运算符的时候,cout 在前,cout 为ostream这种类型的对象。
ostream & operator<< (ostream& o,Student &s1){
    o << s1.name;
    return o;
}

int main() {
    Student s1("fly");
    cout << s1 << endl;
    return 0;
}

在这里插入图片描述

3.输入运算符重载

#include <iostream>
#include <string>
//输入运算符重载
using namespace std;
class Student{
public:
    string name;
};

//对 << 运算符进行重载。
ostream& operator<< (ostream& o, Student &s1){
    o << s1.name ;
    return o;
}

//对 >> 运算符进行重载
istream& operator>> (istream& in, Student &s1){
    in >> s1.name;
    return in;
}

int main() {
    Student s1;

    cout << "请输入学生的姓名:" << endl;
    cin >>  s1;

    //打印学生, 实际上是打印他的名字。
    cout << s1  <<endl ;
    return 0;
}

在这里插入图片描述

4.赋值运算符重载

4.1 拷贝赋值运算

#include <iostream>
#include <string>
//拷贝赋值运算
using namespace std;

class Student{
    string name;
public:
    Student(string name):name(name){
        cout<<"function"<<endl;
    }

    //拷贝赋值
    void operator=(const Student &s){
        name = s.name;//浅拷贝
//        name = new string(*s.name);//深拷贝
    };

    void run(){
        cout<<name<<endl;
    }
};

int main() {
    Student s1("fly");
    Student s2("zhangsan");
    s1 = s2;
    s1.run();
    s2.run();
    return 0;
}

在这里插入图片描述

4.2 移动赋值运算

#include <iostream>
#include <string>

using namespace std;
class Student{
    string *pad_name;
public:
    Student(string pad_name):pad_name(new string(pad_name)){
        cout<<"function"<<endl;
    }

    //拷贝赋值
    void operator=(const Student &s){
        pad_name = s.pad_name;//浅拷贝
//        name = new string(*s.name);//深拷贝
    };

    //移动赋值运算符号
    void operator = (Student&&s){
        delete pad_name;//先自己放弃自己的空间
        pad_name = s.pad_name;//让现在的对象指向源对象空间
        s.pad_name = nullptr;//让把源对象的空间所有权减掉
    }

    void run(){
        cout<<*pad_name<<endl;
    }
};

int main() {
    Student s1("aa");
    Student s2("bb");
    s1 = move(s2);
    s1.run();
    s2.run();
    return 0;
}

在这里插入图片描述

5.调用运算符重载

#include <iostream>

using namespace std;
class Calc{
public:
    int operator()(int val){
        return val <0 ? -val :val;
    }
};
int main(){
    Calc c ;
    int value = c(-10);
    cout<<value<<endl;
    return 0;
}

在这里插入图片描述

6.lambda表达式的语法

在编写lambda表达式的时候,可以忽略参数列表和返回值类型,但是前后的捕获列表和函数体必须包含 , 捕获列表的中括号不能省略,编译根据它来识别后面是否是lambda表达式 ,并且它还有一个作用是能够让lambda的函数体访问它所处作用域的成员。

#include <iostream>
#include <string>

using namespace std;

int main() {
    //示例1:
    [](int a ,int b)->int{return a + b ;} ; //一个简单的加法

    //例子2 如果编译器能推断出来类型。,那么 ->int 也可以省略掉
    [](int a ,int b){return a + b ;} ;


    //如果不需要参数,那么参数列表页可以忽略。至此不能再精简了。
    []{return 3 + 5 ;};


    //1.接收lambda表达式,然后调用
    auto f = [](int m,int n)->int {return m+n;};
    //2.调用lambda表达式
    int result = f(3,4);
    cout<<result<<endl;

    //不接受表达式,直接调用
    int result2 = [](int m,int n){return m-n;}(10,2);
    cout<<result2<<endl;

    return 0;
}

7.lambda的捕获列表的使用

#include <iostream>
#include <string>
//捕获列表的使用
using namespace std;

int main() {

    int m = 10;
    int n = 20;

    //值传递方式捕获 m 和 n , 在lanmbda 表示内部无法修改m和n的值
    auto f1 = [m,n]{return m + n;};
    cout << f1()  << endl; //打印 8

    //引用方式捕获 m 和 n  , 可以在内部修改m 和 n的值
    auto f2 = [&m,&n]{
        m = 99; //这里修改会导致外部的m 也跟着修改。
        return m + n;
    };
    cout << f2()  << endl; //这里打印35
    cout << "m= "<< m << endl; //再打印一次,m 变成30了

    return 0;
}

在这里插入图片描述

8.labmda应用

编写lamdda表达式很简单,但是用得上lambda表达式的地方比较特殊。一般会使用它来封装一些逻辑代码,使其不仅具有函数的包装性,也具有可见的自说明性。有点类似于java里面的匿名内部类。

#include <iostream>
#include <vector>

using namespace std;

int main() {
    vector<int> scores = {80,90,100,22,33,55};

    int result2 = [&]{
        int result = 0;
        for (int s: scores){
            result += s;
        }
        return result;
    }();
    cout<<result2<<endl;
    return 0;
}

在这里插入图片描述


结束!!!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

等待着冬天的风

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值