重载操作符
能够被重载的操作符包括:https://docs.microsoft.com/en-us/cpp/cpp/operator-overloading?view=vs-2019
重载操作符的规则(不包含new delete 操作符)
- 不能定义新的操作符
- 不能对内置类型的操作符进行重载
- 重载操作符要么是a nonstatic class member,要么是a global function。如果是global funtion,如果重载操作符函数需要获取private或protected类成员时,必须声明为该类的friend。对于global function,其参数至少有一个是类/枚举类型,或该类/枚举类型的引用,例如:
- 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的友元函数,注意:对于同一个操作符,可以有多个重载函数。
注意:
- 操作符遵循与内置类型相同的优先级,分组,以及操作数的个数。
- Unary operators declared as member functions take no arguments; if declared as global functions, they take one argument
- Binary operators declared as member functions take one argument; if declared as global functions, they take two arguments.
- If an operator can be used as either a unary or a binary operator (&, *, +, and -), you can overload each use separately.
- 重载操作符不能有默认参数(default arguments)
- 除=号外的所有重载操作符都会被子类(derived classes)继承
- 对于类成员函数的重载操作符,第一个参数总是该重载操作符函数被调用对象的类型(the class in which the operator is declared,or a class derived from the class).
- 重载=
赋值操作符(the assignment operator=),严格地讲=是binary operator。该操作符的声明与其他binary operator相同。有以下注意事项:
- 赋值操作符只能是a nonstatic member function,不能是nonmember function
- 不能被子类继承
- 编译器会为类生成一个默认的赋值操作符函数,如果该类没有任何赋值操作符函数的话
例子:
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
浙公网安备 33010602011771号