【C++】运算符重载

运算符重载

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

加号运算符

目标:实现两个对象相加或类和其他数据类型相加

Animal dog(10);//实例对象
Animal cat(20);//实例对象
Animal pig1 = dog + cat;//对象+对象
Animal pig2 = dog + 10;//对象+整数

重写operator+实现加号运算符重载
有两种实现:成员函数实现和全局函数实现

class Animal{
pubilc:
    Animal(int a){
        this->a = a;    
    }
//成员函数实现 + 号运算符重载
    Animal operator+(const Animal& p) {
        Animal temp;
        temp.a = this->a + p.a;//成员相加
        return temp;//返回临时对象
    }
pubilc:
    int a;//成员变量
}

//全局函数实现 + 号运算符重载
//传参不一样,跟成员函数重载不冲突
Animal operator+(const Animal& p,int b){
        Animal temp;
        temp.a = p.a + b;//成员相加
        return temp;//返回临时对象
}

int main(){
    Animal dog(10);//实例对象
    Animal cat(20);//实例对象
    Animal pig1 = dog + cat;//使用成员函数实现,相当于dog.operator+(cat)
    Animal pig2 = dog + 10;//使用全局函数实现,相当于operator+(dog,10);
}

左移运算符

目标:实现对象的<<链式编程

Animal dog();//实例对象
cout << dog << "hello world" << endl; //链式编程

重写operator<<实现左移运算符重载
成员函数无法实现预期的 << 号运算符重载效果,只能用全局函数实现
左移运算符需要一个左值和一个右值,如果使用成员函数实现,那就是:dog.operator<<(x),左值是对象,右值是传入参数,那么要使用这个重载,对象应写在左值位置,dog<<,这与我们想实现的cout << dog不符合

class Animal{

pubilc:
    int a = 10;//成员变量
    int b = 20;//成员变量
}

//全局函数实现 << 运算符重载
ostream& operator<<(ostream& out,Animal p){
    out << "a:" << p.a << " b:" << p.b;
    return out;//返回ostream类型,主要是考虑到链式编程连续<<的使用
}

int mian(){
    Animal dog;//实例对象
    cout << dog << "hello world" << endl; //链式编程
}

递增运算符

目标:实现对象的++递增运算

Animal dog(10);//实例对象
dog++;
++dog;

重写operator++实现递增运算符重载

class Animal{
public:
//前置++
    Animal& operator++(){
        num++;//先++
        return *this;//再返回
        //返回引用,考虑到++(++a)的情况,应该递增同一个a对象    
    }
//后置++,使用传参int来区分于前置
    Animal operator++(int){
        Animal temp = *this; //记录当前本身的值
        num++;//再++
        return temp;//返回记录的值
    }
pubilc:
    int num = 10;//成员变量
}

int mian(){
    Animal dog;//实例对象
    dog++;
}

赋值运算符

c++编译器默认会给类添加赋值运算符重载operator=, 对属性进行值拷贝
如果类中有属性指向堆区,做赋值操作时也会出现深浅拷贝问题

目标:实现对象的=号赋值运算

Animal p1(18);
Animal p2(20);
Animal p3(30);
p3 = p2 = p1; //赋值操作

重写operator=实现赋值运算符重载

class Animal{
pubilc:
    Animal(int a){
        m_Age = new int(a);//将数据开辟到堆区     
    }
    //重载赋值运算符
    Animal& operator=(Animal &p){
        if (m_Age != NULL){
            delete m_Age;
            m_Age = NULL;
        }
        //m_Age = p.m_Age;  //编译器提供的代码是浅拷贝
        m_Age = new int(*p.m_Age);//提供深拷贝 解决浅拷贝的问题
        return *this; //返回自身
    }
    //有内存申请,应该写析构函数释放申请内存
    ~Person(){
        if (m_Age != NULL){
            delete m_Age;
            m_Age = NULL;
        }
    }
public:
    int *m_Age;
}

int mian(){
    Animal p1(18);
    Animal p2(20);
    Animal p3(30);
    p3 = p2 = p1; //赋值操作
}

关系运算符

目标:实现对象之间的关系运算

Animal dog(10);//实例对象
Animal cat(20);//实例对象
if(dog == cat){
    //对比两个实例
}

重写operator==实现关系运算符重载

class Animal{
pubilc:
    Animal(int a){
        this->a = a;   
    }
    bool operator==(Animal& p){
        if (this->a == p.a){
            return true;
        }
        else{
            return false;
        }
    }
publicint a;
}

int main(){
    Animal dog(10);//实例对象
    Animal cat(20);//实例对象
    if(dog == cat){
        cout << "dog和cat相等" << endl;
    }
}

函数调用运算符

函数调用运算符 () 也可以重载
由于重载后使用的方式非常像函数的调用,因此称为仿函数
仿函数没有固定写法,非常灵活
重写operator()实现函数调用运算符重载
例程:

class MyPrint
{
public:
    void operator()(string text)
    {
        cout << text << endl;
    }
};
void test01()
{
//重载的()操作符 也称为仿函数
    MyPrint myFunc;
    myFunc("hello world");
}
class MyAdd
{
public:
    int operator()(int v1, int v2)
    {
        return v1 + v2;
    }
};
void test02()
{
MyAdd add;
int ret = add(10, 10);
cout << "ret = " << ret << endl;
//匿名对象调用
cout << "MyAdd()(100,100) = " << MyAdd()(100, 100) << endl;
}
int main() {
    test01();
    test02();
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值