C++核心编程7——类和对象之C++运算符重载

1. 运算符重载概念

运算符重载:对已有的运算符重新进行定义,赋予其另一种功能,以适应不同的数据类型

2. 加号运算符重载

作用:两个自定义数据类型相加(eg. 两个person相加)

可以对同一个类的成员进行重载,也可以在不同类之间进行重载。

例如,可以operator+(Person &p1, Person &p2),也可以operator(Person &p1, int number)

总结1:对于内置的数据类型的表达式的运算符是不可能改变的(只能重载自定义的数据类型,C++内置的int,double这种不可重载)

总结2:不要滥用运算符重载

3. 左移运算符重载

作用:输出自定义数据类型

#include <iostream>
#include <string>
#include <math.h>
using namespace std;

class Student 
{
public:
    int age;
    long long ID;
};

//左移运算符只能通过全局函数重载
//注意,返回的是ostream &,当返回的是ostream &时,可以在后续调用的时候使用链式编程一直cout,否则单行就只能cout一次
//返回引用,就可以一直对同一个变量进行操作,如果返回的是值不是引用,就会创建一个新的变量
ostream& operator<< (ostream& cout, Student& s1) 
{
    cout << s1.age;
    cout << " ";
    cout << s1.ID;
    return cout;
}

//构造函数调用
void test1()
{
    Student s1;
    s1.age = 25;
    s1.ID = 3220181084;
    cout << s1 << endl;
}

int main()
{
    test1();
    return 0;
}

4. 递增运算符重载

作用:通过重载递增运算符,实现自己的整型数据

 作业:编写重载递减函数

#include <iostream>
#include <string>
#include <math.h>
using namespace std;

class MyInteger
{
    friend ostream& operator<< (ostream& cout, MyInteger m);

public:
    MyInteger()
    {
        Myint = 0;
    }
    //前置--
    //前置--返回引用,返回变量本身
    MyInteger& operator--()
    {
        --Myint;
        return *this;
    }
    //后置--
    //后置--返回值
    MyInteger operator--(int)//后置++和后置--都要新增一个int占位符用来和前置重载函数进行区分
    {
        MyInteger temp = *this;
        Myint--;
        return temp;
    }

private:
    int Myint;
};

ostream& operator<< (ostream& cout, MyInteger m)
{
    cout << m.Myint;
    return cout;
}

void test1()
{
    MyInteger m;
    cout << --m << endl;
    cout << m << endl;
}

void test2()
{
    MyInteger m;
    cout << m-- << endl;
    cout << m << endl;
}

int main()
{
    //test1();
    test2();
    return 0;
}

5. 赋值运算符重载

案例:在class里面新建一个指针变量(建立在堆区,程序运行结束后需要程序员手动释放),在测试中使用赋值运算。

1. 直接使用赋值运算符(编译器自动提供的是浅拷贝)。当我们在class里面建立析构函数手动释放堆区数据时程序运行会崩溃,原因是编译器自动提供的赋值运算是浅拷贝,p2拷贝的是p1的内存地址。因此在释放时,同一块内存空间会被重复释放,因此会导致错误。

2. 解决办法:使用深拷贝解决问题。为p2创建一块新的内存空间。

 MyInteger& operator= (MyInteger& m)
    {
        //普通浅拷贝构造函数
        //Myint = m.Myint;
        
        //深拷贝构造函数
        if (Myint != NULL)
        {
            delete Myint;
            Myint = NULL;
        }
        Myint = new int(*m.Myint);
        return *this;
    }

 结论:对于建立在堆区的变量,不可使用编译器自己生成的赋值运算符(浅拷贝),而需要自己编写一个深拷贝的赋值运算符。

 

6. 关系运算符重载

作用:重载关系运算符,可以让两个自定义类型对象进行比对操作

7. 函数调用运算符()重载 

 

#include <iostream>
#include <string>
#include <math.h>
using namespace std;

class MyFunc
{
public:
    int operator()(int num1, int num2)
    {
        return num1 - num2;
    }

};

void test1()
{
    MyFunc myS;
    cout << myS(10, 2) << endl;
    //匿名函数对象,可以不用创建myS对象而直接调用重载函数()
    cout << MyFunc()(10,2) << endl;
}

int main()
{
    test1();
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值