Operator is a C + + keyword that is used in conjunction with an operator to represent an operator function that should be understood as a function name as a whole operator=.
This is a method of the C + + extension operator function, although it looks strange, but it is understandable: on the one hand, the use of the operator is consistent with its original, on the other hand, extending its function only through the function of the way (C + +, "function" is implemented by the function).
First, why use operator overloading?
For all operators of the system, in general, only the basic data type and the class provided in the standard library are supported, for the user-defined class, if you want to support basic operations such as comparing size, judging equality, and so on, you need to define a specific implementation of this operator. For example, judging whether two people are the same size, our default rules are based on their age to compare, so, in the design of the person this class, we need to consider the operator = =, and, according to the analysis just now, the basis of the comparison should be ages. So why is it called overloading? This is because, at the time of the compiler implementation, we have provided the basic data type implementation version of this operator, but now his operand becomes the user-defined data type class, so the user is required to provide the implementation of the parameter version.
Second, how to declare an overloaded operator?
A: operator overloading is implemented as a class member function
The overloaded operator is declared in the body of the class, declared in the same way as a normal member function, except that his name contains the keyword operator, followed by a C + + pre-defined operator.
You can declare a predefined = = operator in the following way:
Class person{
Private
int age;
Public
person (int a) {
this->age=a;
}
inline bool operator = = (Const person &PS) const;
};
Here's how it's implemented:
inline bool person::operator== (const person &PS) const
{
if (this->age==ps.age)
return true;
return false;
}
The method is called as follows:
#include
using namespace Std;
int main ()
{
Person P1 (10);
Person P2 (20);
if (P1==P2) cout<< "The Age is equal!" < return 0;
}
Here, because operator = = is a member of the class person function, so the object P1,P2 can call the function, the above if statement, the equivalent of P1 call function = =, the P2 as a parameter of the function to the function, so as to achieve a comparison of two objects.
B: operator overloading implemented as a non-class member function (global function)
For global overloaded operators, the arguments that represent the left operand must be explicitly specified. For example:
#include
#include
using namespace Std;
Class Person
{
Public
int age;
Public
};
BOOL operator== (Person const &P1, Person const & p2)
Satisfies the requirement, the type of the operand to be done is displayed specified
{
if (p1.age==p2.age)
return true;
return false;
}
int main ()
{
Person Rose;
Person Jack;
rose.age=18;
jack.age=23;
if (Rose==jack)
cout<< "OK" < return 0;
}
C: How do you decide to overload an operator with a class member function or a member of a global namespace?
① If an overloaded operator is a class member, the operator is called only if the left operand that is used with him is an object of that class. If the left operand of the operator must be a different type, the operator must be overloaded to a member of the global namespace.
②c++ requires assignment =, subscript [], call (), and member-to-operator must be defined as a class member operator. Any definition of these operators as namespace members will be marked as compile-time errors.
③ If an operand is a class type such as a string class, it is best to define a global namespace member for a symmetric operator such as the Equals operator.
D: Overloaded operators have the following limitations:
(1) Only operators in C + + pre-defined operator set can be overloaded;
(2) for a built-in type operator, its predefined cannot be changed, should not be built-in type overloaded operators, such as, can not change the int type operator + meaning;
(3) Also cannot define other operators for the built-in data type;
(4) Only operators of class types or enumeration types can be overloaded;
(5) Overloaded operators cannot change their operator precedence;
(6) The overloaded operator cannot change the number of operands;
(7) In addition to the () operator, it is illegal to provide default arguments to other overloaded operators;
E: Watch out.
(1) The consequences of the operator first to determine whether its return value is an lvalue, or the right value, if the Lvalue is the most return reference, if it is the right value, then return the value directly;
(2) + number such as the operator no object can accommodate the changed value, it is best to return a value for such cases, otherwise you can only create a temporary object in the operator body to accommodate the changed value, if you create a temporary object in the heap returns a pointer or reference, in the operator function outside the body also need to release it, If the returned object is not a reference or pointer, then the efficiency is relatively low. If a numeric value is returned, it is best to add a conversion function to the type's value in the constructor of the class, such as: The return value is of type int, then it is preferable to have an int type as the constructor of the parameter.
(3) in the increment operator, put an integer parameter, which is the post-increment runner, which is the value returned, no formal parameter for the previous increment, and a reference to return, example:
Class Test
{
Public
Test (x=3) {m_value = x}
Test &operator + + (); Pre-increment
Test &operator + + (int);//post-increment
Private
Int m_value:
};
Test &test::operator + + ()
{
M_value + +; Increment first
return *this; Returns the current object
}
Test Test::operator + + (int)
{
Test tmp (*this); Create a temporary object
M_value + +; Re-increment
return temp; Returning a temporary object
}
(4) because the cast is for the base data type, the conversion to the class type needs to be customized;
(5) Conversion runner overload declaration form: operator type name (); It has no return type, because the type name represents its return type, so the return type is superfluous.
(6) In general, conversion operators and conversion constructors (that is, constructors with one parameter) are reciprocal, and if there is a constructor test (int), then it is better to have a conversion operator int (). This eliminates the need to provide object parameter overloading operators, such as test A1 (1); Test A2 (2); Test A3; a3 = A1+A2; Do not need to overload the + operator, because for the A1+A2 operation, the system may first find there is no definition for the test of the + operator, if not, it will look for the test class conversion function parameter type of the + operator (because it can be + The type of the result is converted to the test object by a conversion function, because the test class has a parameter of type int and a + operator for the int type, so a1+a2 really executes test (int (A1) + int (A2)), which is Test (3);
(7) For conversion operators, there is also a need to note that if there is a Class A conversion function (constructor) with the B parameter, that B can not have a conversion operator, or there is a conversion of two semantics, such as:
Class A{a (b&) {...}}; Class b{operator A () {...}}; Then there is a problem with the following statement:
b b; A (b);//a (b) has a constructor that can be a, or a conversion operator of B
C + + operator keywords