C++ 操作符重载

1. 双目操作符重载

1.1 双目操作符

在这里插入图片描述

1.2 运算类双目操作符 的 重载

  • 友元函数可以写在类的内部,但本质还是友元函数。
#include <iostream>
using namespace std;
class Complex{
public:
    Complex(int r, int i):m_r(r),m_i(i){}
    void print(void)const{
        cout << m_r << "+" << m_i << "i" << endl;
    }

    // operator+ 成员函数形式: 
    // 第一个const 保证表达式是右值, 第二个const 保证右操作数可以是右值(常对象, 常引用才能引用右值)
    // 第三个const保证如果左操作数可以是右值(常对象只能调用常函数)
    // 3个const一个都不能少, 都是为了和内置操作符的语义保持一致(不出现逻辑错误)
    const Complex operator+(const Complex& c)const{
        Complex res(m_r + c.m_r, m_i + c.m_i);
        return res;
    }
private:
    int m_r;
    int m_i;
    // 在类的内部声明友元函数 operator-(也可以把函数声明和定义写在一起, 但本质还是全局函数)
    // 这样在类的外部的operator-可以访问类的所有成员
    friend const Complex operator-(const Complex& l, const Complex r);
};

// operator- 全局函数形式
const Complex operator-(const Complex& l, const Complex r){
    Complex res(l.m_r - r.m_r, l.m_i - r.m_i);
    return res;
}

int main(void){
    Complex c1(1, 2);
    Complex c2(3, 4);
    // 成员函数形式: Complex c3 = c1.operator+(c2) 
    Complex c3 = c1 + c2;
    c3.print();
    // 全局函数形式: Complex c4 = operator-(c2, c1);
    Complex c4 = c2 - c1;
    c4.print();
    return 0;
}
$ ./a.out 
4+6i
2+2i

1.3 赋值类双目操作符 的 重载

在这里插入图片描述

#include <iostream>
using namespace std;
class Complex{
public:
    Complex(int r, int i):m_r(r),m_i(i){}
    void print(void)const{
        cout << m_r << "+" << m_i << "i" << endl;
    }

    // operator+= 成员函数形式
    // 左操作数必须是左值,所以这里不能是常函数
    // 表达式返回值是左操作数,所以返回值类型是 Complex&, 不能加const
    // 有操作数可以是左值或右值,所以加上const
    Complex& operator+=(const Complex& c){
        m_r +=  c.m_r;
        m_i += c.m_i;
        return *this;
    }
    friend Complex& operator-=(Complex& l, const Complex& r);
private:
    int m_r;
    int m_i;
  
};

// operator-= 全局函数形式
Complex& operator-=(Complex& l, const Complex& r){
    l.m_r -= r.m_r;
    l.m_i -= r.m_i;
    return l;
}
int main(void){
    Complex c1(1, 2);
    Complex c2(3, 4);
    
    // 成员函数形式: c1.operator+=(c2);
    (c1 += c2).print();
    c1.print(); 
    
    // 全局函数形式: operator-=(c1, c2);
    c1 -= c2;
    c1.print();

    return 0;
}
$ ./a.out 
4+6i
4+6i
1+2i

2. 单目操作符重载

2.1 单目操作符

在这里插入图片描述

2.1 计算类的单目操作符 的重载

  • 相反数,位反,逻辑非
    在这里插入图片描述
#include <iostream>
using namespace std;
class Integer{
public:
    Integer(int i = 0):m_i(i){}
    // operator- 的成员函数形式
    const Integer operator-(void) const {
        Integer res(-m_i);
        return res;
    }
    void print(void){
        cout << m_i << endl;
    }

    // operator~ 的全局函数形式
    friend const Integer operator~(const Integer& c){
        Integer res(~c.m_i);
        return res;
    }
    
private:
    int m_i;
};


int main(void){
    Integer i(100);
    // 成员函数形式: Integer j = i.operator-(void);
    Integer j = -i;
    j.print();
    // 全局函数形式: j = operator~(i);
    j = ~i;
    j.print();
    return 0;
}
$ ./a.out 
-100
-101

2.2 前缀自增减的单目操作符 的 重载

在这里插入图片描述

2.3 后缀自增减的单目操作符 的 重载

在这里插入图片描述

  • 后缀和前缀的主要区别就是表达式结果的不同
#include <iostream>
using namespace std;
class Integer{
public:
    Integer(int i = 0):m_i(i){}
    // 前++: 成员函数形式
    Integer& operator++(void){
        ++m_i;
        return *this;
    }
    // 后++: 成员函数形式
    const Integer operator++(int){
        Integer old = *this;
        ++*this; //等同于 ++m_i, 是前面代码的复用,更加高级
        return old; 
    }
    void print(void)const{
        cout << m_i << endl;
    }
private:
    int m_i;
};


int main(void){
    Integer i(100);
    //i.operator++();
    (++i).print();
    //i.operator++();
    (i++).print();
    i.print();
    return 0;
}
$ ./a.out 
101
101
102

3. cout、cin 操作符重载

在这里插入图片描述

#include <iostream>
using namespace std;
class Complex{
public:
    Complex(int r, int i):m_r(r),m_i(i){}
    // const: 参数可以接收右值
    friend ostream& operator<<(ostream& os, const Complex& c){
        os << c.m_r << "+" << c.m_i << "i";
    }
    friend istream& operator>>(istream& oi, Complex& c){
        oi >> c.m_r >> c.m_i;
    }
private:
    int m_r;
    int m_i;
  
};

int main(void){
    Complex c1(1, 2);
    Complex c2(3, 4);
    // operator<<(cout, c1);
    cout << c1 << endl;
    
    // operator>>(cout, c2);
    cin >> c2;
    cout << c2 << endl;
    return 0;
}
$ ./a.out 
1+2i
1
1
1+1i

4. new、delete 操作符重载

  • 可以更深入的了解下对象创建和销毁的过程

在这里插入图片描述

  • 这里的static用处:在通过重载的new操作符创建对象时,对象的普通成员函数是无法调用的,因为还没造出来。而加了static的成员函数是没有这个限制的,因为静态成员函数可以理解为限制在类中使用的全局函数。
  • 同理,在执行重载的delete操作符时,对象已经不存在了。不能载通过对象去调用它了。
#include <iostream>
#include <cstdlib>
using namespace std;
class A{
public:
    A(void){
        cout << "A的构造" << endl;
    }
    ~A(void){
        cout << "A的析构" << endl;
    }
    static void* operator new(size_t size){
        cout << "A的new" << endl;
        void* pv = malloc(size);
        return pv;
    }
    static void operator delete(void* p){
        cout << "A的delete" << endl;
        free(p);
    }
};


int main(void){
    // 编译器会把下面的变成这两步
    // 1. A* pa = (A*) A::operator new(sizeof(A));
    // 2. pa->构造函数;
    A* pa = new A;

    // 1. pa->析构函数;
    // 2. A::operator delete(pa);
    delete pa;
}
$ ./a.out 
A的new
A的构造
A的析构
A的delete
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值