c++-运算符重载

本文详细介绍了C++中如何通过友元函数和成员函数实现运算符重载,包括自增运算符、赋值运算符、类型转换运算符的重载示例,以及注意事项,如运算符限制和功能一致性原则。
摘要由CSDN通过智能技术生成

1 概念

C++中可以把部分算符看做成函数,此时运算符也可以重载。

运算符预定义的操作只支持基本数据类型,但是对于自定义类型,也需要类似的运算符操做,此时就可以重新定义这些运算符的功能,使其支持特定类型,完成特定操作。

运算符重载有两种实现方式:

  • 友元函数运算符重载
  • 成员函数运算符重载

2 友元函数运算符重载

#include <iostream>
using namespace std;
class Myint
{
private:
    int a;
public:
    Myint(int a)
    {
        this->a=a;
    }
    int get_int()
    {
        return a;
    }
    //+ 运算符重载声明
    friend Myint operator +(Myint &i,Myint &i2);
};
Myint operator +(Myint &i,Myint &i2)
{
    //触发隐式调用构造函数 int -> Myint
    //    Myint myint(0);
    //    myint.a=i.a+i2.a;
    //return myint.a;
    return i.a+i2.a;
}

int main()
{
    Myint int1(2);//构造对象int1并赋值成员变量a为2
    Myint int2(int1);   // 拷贝构造函数 对象int2 int2.a=2

    Myint int3 = int1 + int2;//对象int1+对象int2,内部成员变量
    cout << int3.get_int() << endl;
    int x=1+2;//运算符 原功能不变
    cout << x<< endl;
    return 0;
}

自增运算符重载

#include <iostream>

using namespace std;

class MyInt
{
private:
    int a;
public:
    MyInt(int a)
    {
        this->= a;
    }
    int get_int()
    {
        return a;
    }
    //+ 运算符重载
    friend MyInt operator +(MyInt &i,MyInt &i2);
    friend MyInt operator ++(MyInt &i); // 前置++
    friend MyInt operator ++(MyInt &i,int); // 后置++,通过哑元区分前后自增(哑元必须是int类型)
};

MyInt operator +(MyInt &i,MyInt &i2)
{
    // 触发隐式调用构造函数 int ->MyInt
//    MyInt myint(0);
//    myint.a = i.a + i2.a;
    return i.+ i2.a;
}
MyInt operator ++(MyInt &i)
{
    return ++i.a;
}
MyInt operator ++(MyInt &i,int)
{
    return i.a++;
}
int main()
{
    MyInt int1(2);
    MyInt int2(int1);   // 拷贝构造函数

    MyInt int3 = int1 + int2;

    cout << int3.get_int() << endl;
    cout << (++int3).get_int() << endl;
    cout << (int3++).get_int() << endl;//后置++自动寻找后置++重载,不用传值
    cout << (int3++).get_int() << endl;
    return 0;
}

3 成员函数运算符重载-友元函数的第一个传入的参数,在成员函数中用this指针替代

成员函数运算符重载相比较于友元函数运算符重载,最大的区别在于,友元函数的第一个传入的参数,在成员函数中用this指针替代。因此成员函数运算符重载,相比较与友元函数运算符重载,参数少一个。

#include <iostream>
using namespace std;
class MyInt
{
private:
    int a;
public:
    MyInt(int a)
    {
        this->= a;
    }

    int get_int()
    {
        return a;
    }
    //+ 运算符重载
    MyInt operator +(MyInt &i2);
    
    MyInt operator ++(); // 前置++
    MyInt operator ++(int); // 后置++
};
MyInt MyInt::operator +(MyInt &i2)
{
    return this->+ i2.a;
}
MyInt MyInt::operator ++()
{
    return ++this->a;
}
MyInt MyInt::operator ++(int)
{
    return this->a++;
}
int main()
{
    MyInt int1(2);
    MyInt int2(int1);   // 拷贝构造函数

    MyInt int3 = int1 + int2;

    cout << int3.get_int() << endl;
    cout << (++int3).get_int() << endl;
    cout << (int3++).get_int() << endl;
    cout << (int3++).get_int() << endl;
    return 0;
}

4 其他运算符重载

部分运算符重载不支持友元函数运算符重载,只支持成员函数运算符重载。比如说(类型转换运算符重载,必须使用成员函数运算符重载)。

4.1 赋值运算符重载‘=’

如果程序员不手动编写赋值运算符重载,则赋值运算符重载会被编译器自动添加。

#include <iostream>
using namespace std;
class MyInt
{
private:
    int a;
public:
    MyInt(int a)
    {
        this->a = a;
    }
    int get_int()
    {
        return a;
    }
    // 编译器自动添加的赋值运算符重载函数
    MyInt & operator =(MyInt &i)
    {
        cout << "我自己添加的赋值运算符重载" << endl;
        //若成员变量包含指针,则赋值运算符重载需要自己new开辟空间,解决浅拷贝的局限性
        this->a = i.a;
        return *this;
    }
};
int main()
{
    MyInt int1(2);
    MyInt int2(int1);   // 拷贝构造函数
    MyInt int3(3);
    int3 = int2;        // 赋值运算符重载
    cout << int3.get_int() << endl;
    return 0;
}

当类中出现指针类型的成员变量时,默认的赋值运算符重载函数类似于默认的浅拷贝构造函数,因此也需要手动编写解决浅拷贝的问题。

4.2 类型转换运算符重载

必须使用成员函数运算符重载,且格式比较特殊。

#include <iostream>

using namespace std;

class MyInt
{
private:
    int a;
    string str = "hello";
public:
    MyInt(int a)
    {
        this->= a;
    }

    int get_int()
    {
        return a;
    }

    // 类型转换运算符重载
    operator int()
    {
        return a;
    }

    operator string()
    {
        return str;
    }
};
int main()
{
    MyInt int1(2);
    int a = int1;//目的,直接用类赋值
    cout << a << endl;
    return 0;
}

5 注意事项

  • 重载的运算符限制再C++语言中已有的运算符范围,不能创建新的运算符。
  • 运算符重载本质上也是函数重载,但是不支持函数默认值设定。
  • 重载之后的运算符不能改变运算符的优先级和结合性,也不能改变运算符的操作数和语法结构。
  • 运算符重载必须基于或包含自定义类型,即不能改变基本数据类型的运算规则。
  • 重载的功能应该与原有的功能相似,避免没有目的滥用运算符重载。
  • 一般情况下,双目运算符建议使用友元函数进行重载,单目运算符建议使用成员函数。

6 函数参数默认值

  • 默认值参数是指给函数赋予一个值,调用时如果没有参数传入,就会使用默认值参数。
  • 默认参数使用时需要注意,从被赋予默认参数的参数开始,后面的参数都要赋予默认参数。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

满山的猴子我的腚最红

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

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

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

打赏作者

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

抵扣说明:

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

余额充值