运算符重载

运算符重载,就是对已有的运算符赋予多重的含义,使同一运算符作用于不同类型的数据时导致不同类型的行为,作用就是扩展c++中已有运算符的范围,使之可以作用于对象,同一运算符对不同操作数,所发生的行为是不同的

  • 运算符的重载的实质是函数重载
  • 可以重载为普通函数,也可以重载为成员函数
  • 把含运算符的表达式转换成对运算函数的调用
  • 运算符被多次重载时,根据实参类型确定

重载为成员函数时,参数个数为运算符目数减一,重载为普通函数时参数个数为运算符目数

赋值运算符的重载

赋值运算符只能重载为成员函数

运算符重载为友元函数

#include <iostream>
#include <algorithm>
#include <cstring>
using namespace std;

class Complex
{
    public:
        double real, imag;
        void Print(){
            cout << real << ',' << imag;
        }
        Complex(double r, double i):real(r), imag(i)
        {}
        Complex operator+(double r);
};

Complex Complex::operator+(double r)
{
    return Complex(real + r, imag);
}

上面的代码中c = c + 5是正确的但是c = 5 + c就是不对的,所以需要再重载

可变长数组

class CArray
{
    int size;
    int *ptr; 
    public:
        //s代表数组元素个数
        CArray(int s = 0);  
        CArray(CArray &a);
        ~CArray();
        //用于在数组尾部添加一个元素v
        void push_back(int v);
        CArray& operator=(const CArray& a);
        int length(){return size;}
        int& CArray::operator[](int i)
        {
            //用以支持根据下标访问数组中的元素
            //如n = a[i]和a[i] = 4这样的语句
            return ptr[i];
        }
};

CArray::CArray(int s):size(s)
{
    if(s == 0)  ptr = NULL;
    else ptr = new int [s];
}

CArray::CArray(CArray &a)
{
    if(!a.ptr)
    {
        ptr = NULL;
        size = 0;
        return ;
    }
    ptr = new int[a.size];
    memcpy(ptr, a.ptr, sizeof(int)* a.size);
    size = a.size;
}
CArray::~CArray()
{
    if(ptr) delete []ptr;
}

CArray& CArray::operator=(const CArray& a)
{
    //防止a = a这样出错
    if(ptr == a.ptr)    return *this;
    //如果数组为空
    if(a.ptr == NULL)
    {
        if(ptr) delete []ptr;
        ptr = NULL;
        size = 0;
        return *this;
    }
    if(size < a.size)
    {
        if(ptr) delete []ptr;
        ptr = new int [a.size];
    }
    memcpy(ptr, a.ptr, sizeof(int)*a.size);
    size = a.size;
    return *this;
}

void CArray::push_back(int v)
{
    if(ptr)
    {
        int* tmp = new int[size + 1];
        memcpy(tmp, ptr, sizeof (int)*size);
        delete []ptr;
        ptr = tmp;
    }
    else
        ptr =  new int[1];
    ptr[size++] = v;
}

流插入运算符和流提取运算符的重载

cout 是在iostream中定义的ostream类的对象

ostream & ostream::operator<<(int n)
{
    //输出要输出的内容
    return *this;
}
#include<iostream>
#include <algorithm>
#include <cstring>

using namespace std;

class Complex
{
    double real, imag;
    public:
        Complex(double r = 0, double i = 0):real(r), imag(i){};
        friend ostream & operator << (ostream & os, const Complex& c);
        friend istream & operator >> (istream & is, const Complex& c);
};

ostream & operator << (ostream & os, const Complex& c)
{
    os << c.real << '+' << c.imag << 'i';
    return os;
}

istream & operator >> (istream & is, Complex & c)
{
    string s;
    is >> s;
    int pos = s.find("+", 0);
    string sTmp = s.substr(0, pos);
    c.real = atof(sTmp.c_str());
    sTmp = s.substr(pos + 1, s.length() - pos - 2);
    c.imag = atof(sTmp.c_str());
    return is;
}

自增自减运算符的重载

自增运算符++、自减运算符有前置和后置之分,为了区分所重载的是前置运算符还是后置运算符,c++规定前置运算符作为一元运算符重载

//重载为成员函数
T & operator++();
T & operator--();
//重载为全局函数
T1 & operator++(T2);
T1 & operator--(T2);

//重载为成员函数
T & operator++(int);
T & operator--(int);
//重载为全局函数
T1 & operator++(T2, int);
T1 & operator--(T2, int);
  • C++不允许定义新的运算符
  • 运算符重载不改变运算符的优先级
  • . 、.*、::、?:、sizeof不能被重载
  • ()、[]、->或者=时运算符重载函数必须声明为类的成员函数
posted @ 2022-12-30 10:52  cxy8  阅读(79)  评论(0编辑  收藏  举报