4.5 运算符重载

4.5 运算符重载

4.5.1 加号/减号运算符重载

4.5.2 左移运算符重载

4.5.3 递增运算符重载

4.5.4 赋值运算符重载

4.5.5 关系运算符重载

4.5.6 函数调用运算符重载


4.5 运算符重载


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

本质

  • 提供一个operator 运算符()函数,使得A operator 运算符(B)的形式可以化简为A 运算符 B的形式


4.5.1 加号/减号运算符重载

作用:实现两个自定义数据类型相加的运算

示例1

//成员函数实现 + / -号运算符重载
#include <stdio.h> 
#include <iostream>
#include <string>
#include <algorithm>
using namespace std;
​
class point{
    public:
        int x,y;
        
        point(){}
        
        point(int a,int b):x(a),y(b) {}
        
        point operator+(const point p){  //成员函数实现 + 号运算符重载
            point t;
            t.x=this->x+p.x;
            t.y=this->y+p.y;
            return t;
        }
        
        point operator-(const point p){  //成员函数实现 - 号运算符重载
            point t;
            t.x=this->x-p.x;
            t.y=this->y-p.y;
            return t;
        }
        
};
​
int main(){
    
    point p1(1,1);
    
    point p2(2,2);
    
    point p3=p2+p1;
    
    cout<<p3.x<<" "<<p3.y<<endl;
    
    p3=p2-p1;
    
    cout<<p3.x<<" "<<p3.y<<endl;
    
    return 0;
    
}

示例2

//全局函数实现 + / -号运算符重载
#include <stdio.h> 
#include <iostream>
#include <string>
#include <algorithm>
using namespace std;
​
class point{
    public:
        int x,y;
        
        point(){}
        
        point(int a,int b):x(a),y(b){}
        
};
​
point operator+(const point &p1,const point &p2){  //全局函数实现 + 号运算符重载
    point t;
    t.x=p1.x+p2.x;
    t.y=p1.y+p2.y;
    return t;
}
​
point operator-(const point &p1,const point &p2){  //全局函数实现 - 号运算符重载
    point t;
    t.x=p1.x-p2.x;
    t.y=p1.y-p2.y;
    return t;
}
​
int main(){
    
    point p1(1,1);
    
    point p2(2,2);
    
    point p3=p1+p2;
    
    cout<<p3.x<<" "<<p3.y<<endl;
    
    p3=p2-p1;
    
    cout<<p3.x<<" "<<p3.y<<endl;
    
    return 0;
    
}

总结

  • 对于内置的数据类型的表达式的的运算符是不可能改变的

  • 不要滥用运算符重载


4.5.2 左移运算符重载


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

注意 :一般使用全局函数实现

示例

//全局函数实现左移重载
#include <stdio.h> 
#include <iostream>
#include <string>
#include <algorithm>
using namespace std;
​
class point{
    public:
        int x,y;
        
        point(){}
        
        point(int a,int b):x(a),y(b){}
        
};
​
//ostream对象只能有一个
ostream& operator<<(ostream &cout,point &p){
    cout<<p.x<<" "<<p.y<<endl;
    return cout; 
}
​
int main(){
    point p1(1,1);
    
    cout<<p1<<"链式输出"<<endl;
    
    return 0;
}

4.5.3 递增运算符重载


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

示例

#include <stdio.h> 
#include <iostream>
#include <string>
#include <algorithm>
using namespace std;
​
class point{
    public:
        int x,y;
        
        point(){}
        
        point(int a,int b):x(a),y(b){}
        
        //前置递增 
        point& operator++(){
            this->x++;
            this->y++;
            return *this;
        }
        
        //后置递增 
        point& operator++(int){  //int用于占位 
            this->x++;
            this->y++;
            return *this;
        }
};
​
int main(){
    
    point p1(1,1);
    
    p1++;
    
    ++p1;
    
    cout<<p1.x<<" "<<p1.y<<endl;
    
    return 0;
    
}

4.5.4 赋值运算符重载


C++编译器至少给一个类添加4个函数

  1. 默认构造函数(无参,函数体为空)

  2. 默认析构函数(无参,函数体为空)

  3. 默认拷贝构造函数,对属性进行值拷贝

  4. 赋值运算符 operator=, 对属性进行值拷贝

如果类中有属性指向堆区,做赋值操作时也会出现深浅拷贝问题

示例:

#include <stdio.h> 
#include <iostream>
#include <string>
#include <algorithm>
using namespace std;
​
class point{
    public:
        int *x,*y;  //开辟到堆区 
        
        point(){}
        
        point(int a,int b){
            x=new int(a);  //将数据开辟到堆区
            y=new int(b);
        }
        
        
        //重载赋值运算符 
        point& operator=(point &p){
            if(this->x!=NULL){
                delete this->x;
                this->x=NULL;
            }
            if(this->y!=NULL){
                delete this->y;
                this->y=NULL;
            }
            
            //this->x=p.x;  //编译器提供的代码是浅拷贝 
            
            this->x=new int(*p.x);  //提供深拷贝 解决浅拷贝的问题
            this->y=new int(*p.y);
            
            return *this;
        }
        
        ~point(){
            if(this->x!=NULL){
                delete this->x;
                this->x=NULL;
            }
            if(this->y!=NULL){
                delete this->y;
                this->y=NULL;
            }
        }
};
​
int main(){
    
    point p1(1,1);
    
    point p2(2,2);
    
    p1=p2;
    
    cout<<*p1.x<<" "<<*p1.y<<endl;
    
    return 0;
    
}

4.5.5 关系运算符重载


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

示例:

#include <stdio.h> 
#include <iostream>
#include <string>
#include <algorithm>
using namespace std;
​
class point{
    public:
        int x,y;
        
        point(int a,int b):x(a),y(b){}
        
        bool operator==(const point &p){
            if(this->x==p.x&&this->y==p.y) return 1;
            else return 0;
        }
};
​
int main(){
    
    point p1(1,1);
    
    point p2(2,2);
    
    if(p1==p2) cout<<"YES"<<endl;
    else cout<<"NO"<<endl;
    
    return 0; 
    
}

4.5.6 函数调用运算符重载


特点

  • 函数调用运算符 () 也可以重载

  • 由于重载后使用的方式非常像函数的调用,因此称为仿函数

  • 仿函数没有固定写法,非常灵活

示例:

#include <stdio.h> 
#include <iostream>
#include <string>
#include <algorithm>
using namespace std;
​
class print{
    public:
        void operator()(auto s){  //重载的()操作符 也称为仿函数
            cout<<s<<endl;
        }
};
​
class add{
    public:
        int operator()(int a,int b){
            return a+b; 
        }
};
​
void test01(){
    
    print p;
    
    p("lys is dog");
    
}
​
void test02(){
    
    add a;
    
    cout<<a(1,2)<<endl;
    
}
​
int main(){
    
    test01();
    
    test02();
    
    return 0;
    
}

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
好的,以下是代码实现: ```c++ #include <iostream> #include <iomanip> #include <cstring> #include <cmath> using namespace std; class Real { public: Real() : num(0) {} Real(double d) : num(d) {} Real operator+(const Real& other) const { double res = num + other.num; if(!check(res)) { cout << "Overflow" << endl; return Real(); } else { return Real(res); } } Real operator-(const Real& other) const { double res = num - other.num; if(!check(res)) { cout << "Overflow" << endl; return Real(); } else { return Real(res); } } Real operator*(const Real& other) const { double res = num * other.num; if(!check(res)) { cout << "Overflow" << endl; return Real(); } else { return Real(res); } } Real operator/(const Real& other) const { double res = num / other.num; if(!check(res)) { cout << "Overflow" << endl; return Real(); } else { return Real(res); } } friend istream& operator>>(istream& is, Real& r) { is >> r.num; return is; } friend ostream& operator<<(ostream& os, const Real& r) { os << setiosflags(ios::fixed) << setprecision(2) << r.num; return os; } private: bool check(double d) const { return !isnan(d) && !isinf(d) && d <= 3.4e38 && d >= -3.4e38; } double num; }; int main() { Real a, b; char op; while(cin >> a >> op >> b) { switch(op) { case '+': cout << a + b << endl; break; case '-': cout << a - b << endl; break; case '*': cout << a * b << endl; break; case '/': cout << a / b << endl; break; default: break; } } return 0; } ``` 我们定义了一个名为Real的类,其中包含了检查数据范围的函数check(),以及重载的四则运算符,还有输入输出流运算符。在主函数中,读入数据后根据运算符进行相应的计算,并输出结果。如果溢出则输出"Overflow"。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

浪漫主义狗

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

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

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

打赏作者

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

抵扣说明:

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

余额充值