一元运算符重载

参考:Overloading Unary Operators

学习一元运算符(unary operator)重载

一元运算符

可被重载的一元运算符如下:

  • 逻辑或:!
  • 取地址:&
  • 补足:~
  • 指针取消引用:*
  • 一元正:+
  • 一元负:-
  • 递增:++
  • 递减:--

格式

除了递增和递减运算符外,其他一元运算符重载的格式如下:

// 非静态成员函数
ret-type operator op ()
// 全局函数
ret-type operator op ( arg )
  • ret-type表示返回值
  • op表示运算符号
  • arg表示参数,全局函数需要有一个参数

示例一

定义类Point,重载一元正运算符

// increment_and_decrement1.cpp
class Point {
public:
    friend Point &operator+(Point &point);

    // Define default constructor.
    Point() { _x = _y = 3; }

    // Define accessor functions.
    int x() { return _x; }

    int y() { return _y; }

    void print() {
        cout << "x = " << _x << " y = " << _y << endl;
    }

private:
    int _x, _y;
};

Point &operator+(Point &point) {
    point._x = -point._x;
    point._y = -point._y;
    return point;
}

int main() {
    Point point;

    point.print();

    Point tmp = +point;

    tmp.print();

    tmp = +point;

    tmp.print();

    // 返回对象是否相同
    cout << &tmp << endl;
    cout << &point << endl;
}

递增和递减

参考:Increment and Decrement Operator Overloading (C++)

有两种类别的递增和递减运算符:

  1. 前增(preincrement)和前减(predecrement
  2. 后增(postincrement)和后减(postdecrement

当重载运算符函数时,可以为这些运算符的前缀和后缀版本实现单独的版本。为了区分这两者,遵循以下规则:运算符的前缀形式的声明方式与任何其他一元运算符完全相同;后缀形式接受int类型的附加参数

注意:为递增或递减运算符的后缀形式指定重载运算符时,附加参数的类型必须为int,指定任何其他类型都会生成错误

int参数仅为了区分前缀和后缀的区别,通常不对该参数进行操作,不过也可以自定义

示例二

定义类Point,实现前增/前减/后增/后减运算符的重载

// increment_and_decrement1.cpp
class Point {
public:
    // Declare prefix and postfix increment operators.
    Point &operator++();       // Prefix increment operator.
    Point operator++(int);     // Postfix increment operator.

    // Declare prefix and postfix decrement operators.
    Point &operator--();       // Prefix decrement operator.
    Point operator--(int);     // Postfix decrement operator.

    // Define default constructor.
    Point() { _x = _y = 0; }

    // Define accessor functions.
    int x() { return _x; }

    int y() { return _y; }

    void print() {
        cout << "x = " << _x << " y = " << _y << endl;
    }

private:
    int _x, _y;
};

// Define prefix increment operator.
Point &Point::operator++() {
    _x++;
    _y++;
    return *this;
}

// Define postfix increment operator.
Point Point::operator++(int) {
    Point temp = *this;
    // 调用前增
    ++*this;
    return temp;
}

// Define prefix decrement operator.
Point &Point::operator--() {
    _x--;
    _y--;
    return *this;
}

// Define postfix decrement operator.
Point Point::operator--(int) {
    Point temp = *this;
    // 调用后增
    --*this;
    return temp;
}

int main() {
    Point point;

    point.operator++();
    point.print();
    point.operator++(2);
    point.print();
    Point tmp = point.operator++();
    tmp.print();

    // 返回对象是否相同
    cout << &tmp << endl;
    cout << &point << endl;
}

如果设置为全局函数重载,格式如下:

friend Point& operator++( Point& )      // Prefix increment
friend Point& operator++( Point&, int ) // Postfix increment
friend Point& operator--( Point& )      // Prefix decrement
friend Point& operator--( Point&, int ) // Postfix decrement