c++加号运算符重载

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

加号运算符重载:实现两个自定义数据类型相加的运算

当我们想让两个自定义数据类型对象进行相加运算(如上图 person p3 = p1 + p2),编译器无法理解我们的需求,导致无法相加。这时候我们需要进行加号运算符重载,使编译器理解我们的需求。

class person
{
public:
    int m_a;
    int m_b;
};

我们先定义一个person类,里面有两个属性m_a和m_b。

void test()
{
    person p1;
    p1.m_a = 10;
    p1.m_b = 10;
    person p2;
    p2.m_a = 10;
    p2.m_b = 10;
    person p3 = p1 + p2;
}
int main(){
    test01();

    return 0;
}

我们写一个test函数,并在主函数里调用test这个函数。在里面建立person两个对象p1和p2,并且对p1和p2的属性进行赋值操作。我们想计算的结果为person p3 = p1 + p2,但此时这里肯定是错误的,因为编译器不知道我们希望p1和p2的哪些属性进行相加,此时我们就要进行加号运算符重载。

加号运算符重载有两种方法:

1.用成员函数重载加号运算符。

2.用全局函数重载加号运算符。

先看第一种,用成员函数重载运算符。下面是代码实现过程。

#include<iostream>
using namespace std;
//加号运算符重载
class person
{
public:
     person operator+(person &p)
     {   
         person temp;
         temp.m_a = this->m_a + p.m_a;
         temp.m_b = this->m_b + p.m_b;
         return temp;
     }
    int m_a;
    int m_b;
};

实现加法运算符的关键字是operator+。我们这里用的是类中的成员函数进行加号运算符重载,因此需要建立一个对象来调用类中的这个成员函数,如果我们此时需要两个对象进行相加,则需要在形参列表内再传入一个对象。这里使用引用传递的方式,将p这个对象的数据直接传进来,而值传递却是要创造一个对象的副本再传入,相比引用传递来说效率更低一些。

我们在这个函数里定义一个person类的局部对象temp,实现思路是使temp的m_a等于调用这个成员函数的对象本体的m_a加上传入的对象的m_a,temp的m_b等于调用这个成员函数的对象本体的m_b加上传入的对象的m_b,然后再将temp这个局部对象进行返回,这样就实现了加号运算符的重载。这里的this指针指向被调用的成员函数所属的对象。

class person
{
public:
    person(int age)
    {
        age = age;
    }
    int age;
};
void test01()
{
    person p(18);
    cout << "p1 age = " << p.age << endl;
}

通俗来讲,在上面代码我创建了一个对象p。在类中我写了一个有参构造函数,我在形参列表中传入了一个整型数据age,但是我在类的属性中也定义了一个age,这时我们发现形参列表中数据名称和类中数据名称相同,这时运行代码,对象p调用有参构造函数并传入年龄为18会发生乱码,因为编译器无法识别age。此时就要用到this指针来避免出现这种问题。

class person
{
public:
    person(int age)
    {
        //this指针指向被调用的成员函数所属的对象
        this->age = age;
    }
    int age;
};
void test01()
{
    person p(18);
    cout << "p1 age = " << p.age << endl;
}

this指针指向被调用的成员函数所属的对象。也就是说,现在这个this指针在构造函数里,那么谁调用这个构造函数,这个this指针就指向谁。这里对象p调用了构造函数,那么这个this指针就指向p,this->age就代表了对象p中的age,然后编译器就可以分清楚两个age,这里就可以顺利将传入的18岁传给了p的年龄。

#include<iostream>
using namespace std;
//加号运算符重载
class person
{
public:
     person operator+(person &p)
     {   
         person temp;
         temp.m_a = this->m_a + p.m_a;
         temp.m_b = this->m_b + p.m_b;
         return temp;
     }
    int m_a;
    int m_b;
};

言归正传。这里的返回值类型为什么是值返回方式person而不是引用返回person&呢?                       因为这里我们返回的temp是一个局部对象,局部对象被储存在栈区,栈区的内存在函数执行完毕后会被系统自动释放,也就是说在这个operator+这个函数运行结束后temp就会被系统释放掉,因为我们选择值返回方式是将这个局部对象temp的数据浅拷贝一份再返回,就可以达到成功返回数据的目的。如果这里使用引用返回,那么此时引用将指向了一块没有被定义的内存,指向了一个空的对象,就会发生错误。

void test01()
{
    person p1;
    p1.m_a = 10;
    p1.m_b = 10;
    person p2;
    p2.m_a = 10;
    p2.m_b = 10;
    person p3 = p1 + p2;
    cout << "p3.m_a = " << p3.m_a << endl;
    cout << "p3.m_b = " << p3.m_b << endl;
}
int main(){
    test01();

    return 0;
}

之后我们创建测试函数就可以直接写person p3 = p1 + p2,编译器就可以识别这行代码,完成相加运算。之后分别输出p3的m_a和m_b就可以得到结果。

2.用全局函数进行加号运算符重载


 person operator+(person &p1, person &p2)
   {
     person temp;
     temp.m_a = p1.m_a + p2.m_a;
     temp.m_b = p2.m_b + p2.m_b;
     return temp;
   }

既然是全局函数,那么这个函数就是在类外的,因此我们想要实现两个对象的相加,就要在形参列表传入两个对象的数据。其它过程与成员函数进行加号运算符重载类似。

加号运算符重载本质调用:

    //成员函数重载本质调用
    person p3 = p2.operator+(p1);
    person p3 = p1 + p2;//简化形式
    cout << "p3.m_a = " << p3.m_a << endl;
    cout << "p3.m_b = " << p3.m_b << endl;
    //全局函数重载本质调用
    person p3 = operator+(p1, p2);

我们所写的person p3 = p1 + p2其实是简化形式,加号运算符本质调用已经列在上面,本质就是对函数进行调用并在形参列表传入参数即可。

有说的有问题的地方接受批评,欢迎指正!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值