重载操作符

能够被重载的操作符包括:https://docs.microsoft.com/en-us/cpp/cpp/operator-overloading?view=vs-2019

重载操作符的规则(不包含new delete 操作符)

  1. 不能定义新的操作符
  2. 不能对内置类型的操作符进行重载
  3. 重载操作符要么是a nonstatic class member,要么是a global function。如果是global funtion,如果重载操作符函数需要获取private或protected类成员时,必须声明为该类的friend。对于global function,其参数至少有一个是类/枚举类型,或该类/枚举类型的引用,例如:
  4. C++中有一条规则是每个重载的operator必须带有一个用户定义类型(user-defined type)的参数,例如对于类型T,重载operator+,不能定义const T operator+(int a,int b) 即使int能隐式转换为T,因为这两个参数都是int,但是没有用户定义的类型T,会产生错误。
// rules_for_operator_overloading.cpp
class Point
{
public:
    Point operator<( Point & );  // Declare a member operator
                                 //  overload.
    // Declare addition operators.
    friend Point operator+( Point&, int );
    friend Point operator+( int, Point& );
};

  在上述代码中,<操作符是类的一个成员函数;+操作符被声明为global函数,且是Point的友元函数,注意:对于同一个操作符,可以有多个重载函数。

注意:

  1. 操作符遵循与内置类型相同的优先级,分组,以及操作数的个数。
  2. Unary operators declared as member functions take no arguments; if declared as global functions, they take one argument
  3. Binary operators declared as member functions take one argument; if declared as global functions, they take two arguments.
  4. If an operator can be used as either a unary or a binary operator (&, *, +, and -), you can overload each use separately.
  5. 重载操作符不能有默认参数(default arguments)
  6. 除=号外的所有重载操作符都会被子类(derived classes)继承
  7. 对于类成员函数的重载操作符,第一个参数总是该重载操作符函数被调用对象的类型(the class in which the operator is declared,or a class derived from the class).

 

  • 重载= 

赋值操作符(the assignment operator=),严格地讲=是binary operator。该操作符的声明与其他binary operator相同。有以下注意事项:

  1. 赋值操作符只能是a nonstatic member function,不能是nonmember function
  2. 不能被子类继承
  3. 编译器会为类生成一个默认的赋值操作符函数,如果该类没有任何赋值操作符函数的话

例子:

class Point
{
public:
    int _x, _y;

    // Right side of copy assignment is the argument.
    Point& operator=(const Point&);
};

// Define copy assignment operator.
Point& Point::operator=(const Point& otherPoint)
{
    _x = otherPoint._x;
    _y = otherPoint._y;

    // Assignment operator returns left side of assignment.
    return *this;
}

int main()
{
    Point pt1, pt2;
    pt1 = pt2;
}

赋值操作符在赋值操作完成后返回一个对象,以保留赋值操作符的行为。这样就允许赋值链(chaining of assignments)操作,例如:

pt1=pt2=pt3;

注意:赋值操作符与赋值构造函数不同,赋值构造函数是在一个对象被创建时调用,而赋值操作符则是对已存在的对象进行赋值:

Point pt3=pt1;//这里调用的是赋值构造函数,pt1作为参数传入构造函数,然后创建pt3

Point pt4;  //调用默认构造函数,或无参数的构造函数

pt4 = pt1;//这里调用的是赋值操作符,pt4已经被构造过了,然后通过assignment operator=对其进行赋值。

  • 重载==

重载==操作符后,可直接使用==判断两个对象是否相等,也可使用<algorithm>中的例如find函数在容器中查找

bool operator==(const ShExemptShip& other)
    {
        if (this->shipMmsi != other.shipMmsi)
        {
            return false;
        }
        if (this->shipType != other.shipType)
        {
            return false;
        }
        if (this->shipName != other.shipName)
        {
            return false;
        }
        if (this->shipLocalName != other.shipLocalName)
        {
            return false;
        }

        return true;
    }
  • 重载<

重载<操作符后,可调用<algorithm>中的sort函数进行排序,也可使用<直接比较两个对象。

bool operator<(const MyClass& other) const
{
    return data <  other.data;
}

 

  • 重载()

The function-call operator, invoked using parentheses, is a binary operator.使用括号调用的函数调用运算符是一个二进制运算符。

注意:

  ()操作符必须是:nonstatic member function

  ()操作符可以重载,

重载后可通过 类名(参数)  的形式对重载的()操作符进行调用,例如:

// even_functor.cpp
// compile with: /EHsc
#include <algorithm>
#include <iostream>
#include <vector>
using namespace std;

class FunctorClass
{
public:
    // The required constructor for this example.
    explicit FunctorClass(int& evenCount)
        : m_evenCount(evenCount) { }

    // The function-call operator prints whether the number is
    // even or odd. If the number is even, this method updates
    // the counter.
    void operator()(int n) const {
        cout << n;

        if (n % 2 == 0) {
            cout << " is even " << endl;
            ++m_evenCount;
        } else {
            cout << " is odd " << endl;
        }
    }

private:
    // Default assignment operator to silence warning C4512.
    FunctorClass& operator=(const FunctorClass&);

    int& m_evenCount; // the number of even variables in the vector.
};

int main()
{
    // Create a vector object that contains 9 elements.
    vector<int> v;
    for (int i = 1; i < 10; ++i) {
        v.push_back(i);
    }

    // Count the number of even numbers in the vector by
    // using the for_each function and a function object.
    int evenCount = 0;
    for_each(v.begin(), v.end(), FunctorClass(evenCount));

    // Print the count of even numbers to the console.
    cout << "There are " << evenCount
        << " even numbers in the vector." << endl;
}

 重载operator+

  重载operator+返回类型最好是const

 

posted @ 2020-07-01 10:26  adfas  阅读(261)  评论(0)    收藏  举报