Skip to content

cpp_operator_overload

ShenYj edited this page Apr 15, 2024 · 2 revisions

operator overload

运算符重载

运算符重载(操作符重载):可以为运算符增加一些新的功能

全局函数、成员函数都支持运算符重载

优先选择成员函数重载,比如自加,连续输入输出这种成员函数重载无法满足时,再考虑使用全局函数重载的方式

  • 全局函数

    .

  • 成员函数

    成员函数重载

    class Point {
    public:
        int m_x;
        int m_y;
    
        Point(int x, int y) :m_x(x), m_y(y) { }
        
        Point operator+(const Point &p) const {
            return Point(this.m_x + p.m_x, this.m_y + p.m_y);
        }
    };
  • 前置++、后置++

    c++ 中通过增加一个 int 类型参数(固定的)表示为后置++

    /// 前置++
    void operator++() {
        ...
    }
    /// 后置++
    void operator++(int) {
        ...
    }

补充

  • 使用对象类型作为参数、返回值时会产生不必要的中间对象,不建议这样使用,所以推荐参数类型为引用或指针
  • 使用 const 引用,可以接收 const对象,也可以是非 const,参数接收的范围更广了,还能限制参数被修改,所以形参带有const是 C++ 中很常见的写法

输出

  • 重载输出函数

    class Point {
    public:
        friend void operator<<(ostream &, const Point &);
        int m_x;
        int m_y;
    
        Point(int x, int y) :m_x(x), m_y(y) { }
    };
    
    /// 作为全局函数,就可以决定左边和右边分别是谁
    /// 左边参数是cout对象 output stream
    /// 右边参数是要被输出的对象
    /// 类似于 oc的 description 方法, 通过这种运算符重载的方式,打印对象
    ostream &operator<<(ostream &cout, const Point &point) {
        cout << "(" << point.m_x << "," << point.m_y << ")";
        return cout;
    }
    
    int main() {
    
        Point p1(10, 20);
        Point p2(10, 30);
        cout << p1;
    
        /// 连续打印
        cout << p1 << p2 << endl;
    }

输入

  • 重载输入函数

    class Point {
    public:
        
        friend istream &operator>>(istream &cin, Point &point);
    
        int m_x;
        int m_y;
    
        Point(int x, int y) :m_x(x), m_y(y) { }
    };
    
    /// 左边参数istream 类型是: input stream
    istream &operator>>(istream &cin, Point &point) {
        cin >> point.m_x;
        cin >> point.m_y;
        return cin;
    }
    
    int main() {
    
        Point p1(10, 20);
        Point p2(20, 30);
    
        cin >> p1 >> p2;
    }

父类

class Person {
    /// 私有
    int m_age;
    Person &operator=(const Person &person) {
        m_age = person.m_age;
    }
public:
    
};

class Student: public Person {
public:
    int m_score;
    void &operator=(const Student &student) {
        /// 私有无法访问
        //m_score = student.m_score;
        Person::operator=(student) // 调用父类的重载,将父类的成员页拷贝

        m_score = student.int m_score;
    }
};

仿函数

将一个对象当作一个函数一样来使用

对比普通函数,它作为对象可以保存状态

class Sum {
    int m_age;
public:
    int operator()(int a, int b) {
        return a + b;
    }
};

int main() {
    Sum sum;
    cout << sum(10, 20) << endl;

    return 0;
}

运算符重载注意点

  • 有些运算符不可以被重载,比如

    • 对象成员访问运算符:.
    • 域运算符:::
    • 三目运算符:?:
    • sizeof
  • 有些运算符只能重载为成员函数,比如

    • 赋值运算符:=
    • 下标运算符:[ ]
    • 函数运算符:( )
    • 指针访问成员:->

Getting Started

Social

Clone this wiki locally