C++运算符重载

(1)加法运算符重载:

#include <iostream>
#include <cstring>
using namespace std;
//运算符重载
//对于内置数据类型,编译器已经预置好
// 1.成员函数实现重载
class Person
{
public:
/*
    //本质 Person p3 = p1.operator+(p2)
    Person operator+(Person &p)
    {

        this->m_A += this->m_A + p.m_A;
        this->m_B += this->m_B + p.m_B;
        return *this;

    }
*/
    int m_A;
    int m_B;
};
// 2.全局函数重载+号 Person p3 = operator+(p1,p2)
Person operator+(Person &p1,Person &p2)
{
    Person temp;
    temp.m_A = p1.m_A+p2.m_A;
    temp.m_B = p1.m_B+p2.m_B;
    return temp;
}
Person operator+(Person &p1,int num)
{
    Person temp;
    temp.m_A = p1.m_A+num;
    temp.m_B = p1.m_B+num;
    return 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;
    p3 = p2+100;
    cout << "p3.m_A="<<p3.m_A<<endl;
    cout << "p3.m_B="<<p3.m_B<<endl;

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

(2)左移运算符的重载也有两种
1.成员函数

ostream& operator<<(ostream &cout)
{
    cout << "m_A = "<<this->m_A<<" m_B = "<<this->m_B;
    return cout;
}
//调用:p<<cout<<"hello"<<endl;

但如果实现cout<<p<<endl;这种形式必须使用
2.全局函数实现重载 完整代码如下:
需要强调的是cout为C++内置ostream 对象 是唯一的 返回的时候要用引用的格式 因为值传递会有一个复制的过程

#include <iostream>
#include <cstring>
using namespace std;
class Person
{
public:
    int m_A;
    int m_B;
};

ostream& operator<<(ostream &cout,Person &p) //本质 operator<< (cout, p)简化为cout << p
{
    cout << "m_A = "<<p.m_A<<" m_B = "<<p.m_B;
    return cout;
}
void test01()
{
    Person p;
    p.m_A = 10;
    p.m_B = 10;
    cout<<p<<"hello"<<endl;
}
int main()
{
    test01();
    return 0;
}

3.递增运算符重载
递增有前置后置之分
对于前置 可返回引用
因为主要是使用this指针做递增
而对于后置 只可返回值 因为内部涉及局部变量 而局部变量不可返回引用。
除此之外
1、代码里涉及到了重载<<运算符 需要注意应当使用值传递 而不能用引用 原因是因为后置递增
2.前置后置函数重载不可依靠返回值不同实现 编译器内置了使用(int)占位符进行区分

#include <iostream>
#include <cstring>
using namespace std;
//递增运算符重载
//自定义整型
class MyInteger
{
    friend ostream& operator<<(ostream& cout, MyInteger myint);
public:
    MyInteger()
    {
        m_Num = 0;
    }
    //重载前置++运算符
    MyInteger& operator++()
    {
        ++this->m_Num;
        return *this;
    }
    //重载后置++运算符
    MyInteger operator++(int) //由于返回类型不能用作函数重载条件 因此使用int用作区分
    {
        //先 记录当时结果
        MyInteger temp = *this;
        //后 递增
        m_Num++;
        //最后讲记录结果返回
        return temp;

    }
private:
    int m_Num;
};
//重载<<运算符
ostream& operator<<(ostream& cout, MyInteger myint)
{
    cout <<myint.m_Num;
    return cout;
}
void test02()
{
    MyInteger myint;
    cout << myint++<<endl;
    cout << myint <<endl;
    cout << ++myint <<endl;
}
int main()
{
    test02();
    return 0;
}

则递减运算符如下所示:

#include <iostream>
#include <cstring>
using namespace std;
//递增运算符重载
//自定义整型
class MyInteger
{
    friend ostream& operator<<(ostream& cout, MyInteger myint);
public:
    MyInteger()
    {
        m_Num = 0;
    }
    //重载前置++运算符
    MyInteger& operator--()
    {
        --this->m_Num;
        return *this;
    }
    //重载后置++运算符
    MyInteger operator--(int) //由于返回类型不能用作函数重载条件 因此使用int用作区分
    {
        //先 记录当时结果
        MyInteger temp = *this;
        //后 递增
        m_Num--;
        //最后讲记录结果返回
        return temp;
    }
private:
    int m_Num;
};
//重载<<运算符
ostream& operator<<(ostream& cout,MyInteger myint)
{
    cout<<myint.m_Num;
    return cout;
}
void test02()
{
    MyInteger myint;
    cout << myint--<<endl;
    cout << myint <<endl;
    cout << --myint <<endl;
}
int main()
{
    //test01();
    test02();
    return 0;
}

4.赋值运算符重载
C++编译器默认给类提供了赋值预算符 不过只能进行值拷贝 与默认拷贝构造函数类似 其容易造成浅拷贝现象,当涉及到堆区内存时(new)时 需要重构。
重构的原则是应当先判断是否有属性在堆区,如果有先释放干净 在深拷贝,注意链式原则。

Person& operator=(Person &p)
{
    //应该先判断是否有属性在堆区,如果有先释放干净 在深拷贝
    if(m_age != NULL)
    {
        delete m_age;
        m_age = NULL;
    }
    m_age = new int(*p.m_age);
    return *this;
}

完整demo

#include <iostream>
#include <cstring>
using namespace std;
//赋值运算符重载
class Person
{
    friend void test01();
public:
    Person(int age)
    {
        m_age = new int (age);
    }
    Person& operator=(Person &p)
    {
        //应该先判断是否有属性在堆区,如果有先释放干净 在深拷贝
        if(m_age != NULL)
        {
            delete m_age;
            m_age = NULL;
        }
        m_age = new int(*p.m_age);
        return *this;
    }
    ~Person()
    {
        if(m_age != NULL)
        {
            delete m_age;
            m_age = NULL;
        }
       
    }
private:
    int *m_age;

};
void test01()
{
    Person p1(18);
    Person p2(20); //浅拷贝 当释放时容易崩溃
    Person p3 = p2 = p1;
    cout << "p1.age:"<<*p1.m_age<<endl;
    cout << "p2.age:"<<*p2.m_age<<endl;
    cout << "p3.age:"<<*p3.m_age<<endl;
}
int main()
{
    test01();
    return 0;
}

4.关系运算符

#include <iostream>
#include <cstring>
using namespace std;
//赋值运算符重载
class Person
{
public:
    Person(string name, int age)
    {
        m_Name = name;
        m_Age = age;
    }
    bool operator==(Person &p)
    {
        if(this->m_Name == p.m_Name && this->m_Age == p.m_Age)
            return true;
        else 
            return false;
    }
    string m_Name;
    int m_Age;
   
};
void test01()
{
    Person p1("Tom", 18);
    Person p2("Tom1", 18);
    if (p1 == p2)
    {
        cout <<"p1 == p2\n";
    }
    else
    {
        cout <<"p1 != p2\n";
    }
}
int main()
{
    test01();
    return 0;
}

5.仿函数 对()的重载

void operator()(string test)
{
    cout<<test<<endl;
}
//匿名对象也可以使用仿函数
Myprint()("hello");
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值