operator overload
Redefine existing operators in the form of functions to complete specific operations;
Make the same operator complete different operations according to different objects.
Operator overloaded function
A special function called operator < operator >;
The compiler automatically converts the object operation expression into the call of the corresponding operator overloaded function;
Operator overloaded functions are usually implemented by member functions or friend functions of classes;
Overloaded operators have only monocular and binocular operands, and at least one of the operands is an object.
Overloaded operators are not allowed in C + +
operator | Meaning of operator |
---|---|
?: | Ternary operator |
. | member operator |
.* | Member pointer operator |
:: | scope resolution operator |
# | Preprocessing macro parameter operator, serialization operator |
## | Preprocessing macro parameter operator, tag paste operator |
Overloadable operator category
Operator category | explain | Some examples |
---|---|---|
Special operator | Can only be implemented with member functions | Assignment =: operator = (& / & &) Type conversion (): operator type () Subscript operator []: type operator [] (formal parameter) Function call operator (): type operator () (formal parameter table) |
Friend operator | Can only be implemented with non member functions; A friend function is a non member function | cout<<obj cin>>obj User defined literal UDL, C11 NEW |
Common operator | Both member and non member functions can be implemented | Monocular operators, such as + +-- Binocular operators, such as arithmetic +, relation <, logical operator = =, new/delete operator |
Define operators with member functions
Overloaded addition operator
In the operation of Complex complex numbers, the add operator is overloaded with the add member function
#include<iostream> using namespace std; class Complex{ double real,image; public: Complex(double a=0,double b=0) { real=a;image=b; } Complex operator +(const Complex &x) { Complex t; t.real=real+x.real; t.image=image+x.image; return t; } void print() { cout<<real<<"\t"<<image<<endl; } }; int main() { Complex a(1,2),b(3,4),c; c=a+b; c.print(); }
Operation results:
Key points of operator overloading
- Defining an operator overloaded function should maintain the semantics of the operator and cannot be changed at will;
- Converting an expression into an operator overloaded function call shall comply with the priority and associativity of the operator;
- The binocular operator is implemented with the member function. The current operand is the left operand, and the right operand can be an object or a basic type value.
- The result and return value of an operator overloaded function should be consistent with the calculation of the operator.
- To change the operator is to change the current object and return it as a result;
- The return type of the function should be "< class name > &"
- The last sentence in the function body is often return *this.
#include<iostream> using namespace std; class Complex{ double real,image; public: Complex(double a=0,double b=0) { real=a;image=b; } Complex operator +(double x)//If you want to add 4.5, change the parameter to double { Complex t; t.real=real+x; t.image=image; return t; } void print() { cout<<real<<"\t"<<image<<endl; } }; int main() { Complex a(1,2),c; c=a+4.5; c.print(); }
Operation results:
//Compare self incrementing pre operator and self incrementing post operator overloading #include<iostream> using namespace std; class Complex{ double real,image; public: Complex(double a=0,double b=0) { real=a;image=b; } Complex operator +(const Complex &x) { Complex t; t.real=real+x.real; t.image=image+x.image; return t; } Complex &operator++()//Front { real++; image++; return *this; } Complex operator++(int)//Post { Complex t=*this; real++; image++; return t; } void print() { cout<<real<<"\t"<<image<<endl; } }; int main() { Complex a(1,2),b(3,4),c,x; c=a+b; c.print(); x=++c; x.print(); x=c++; x.print(); c.print(); return 0; }
Operation results:
friend function
- A friend function of class C is a function modified with the keyword friend, so that it can access all members of class C.
- A friend function can be a global function, a member function in another class B, or all member functions of a in a class (described with friend class A).
Key points of friend function
- A friend function is not a member function of a class, so there is no this pointer in the function body. The reference or pointer of the object is often used as the formal parameters of the friend function, and the members of the object are accessed through these formal parameters in the function body.
- The access rights specified in the class are invalid for friend functions. Therefore, placing the friend function description in the private part, public part or protected part of the class has the same effect.
- Use friend functions with caution. An important feature of class is encapsulation, and friend functions destroy the encapsulation of class. In addition to implementing some specific operator overloaded functions, friend functions should be avoided as much as possible.
- The friend function of a class is not its own member, so it cannot be inherited by the derived class of the class.
Friend function definition operator overloaded function
//Overloading addition operators with friend functions #include<iostream> using namespace std; class Complex{ double real,image; public: Complex(double a=0,double b=0) { real=a;image=b; } void print() { cout<<real<<"\t"<<image<<endl; } friend Complex &operator +(const Complex&,const Complex&);//Friend prototype description }; Complex &operator +(const Complex &a,const Complex &b) { Complex t; t.real=a.real+b.real; t.image=a.image+b.image; return t; } int main() { Complex a(1,2),b(3,4),c; c=a+b; c=operator+(a,b); //equivalence a.print(); b.print(); c.print(); return 0; }
Operation results:
Overloading of unary operators implemented by friend functions
//The overloading of unary operator self increasing (pre and post) operators is realized by using friend functions #include<iostream> using namespace std; class Complex{ double real,image; public: Complex(double a=0,double b=0) { real=a;image=b; } Complex & operator +(const Complex &x) { Complex t; t.real=real+x.real; t.image=image+x.image; return t; } void print() { cout<<real<<"\t"<<image<<endl; } friend Complex &operator ++(Complex &x); friend Complex operator ++(Complex &x,int); }; Complex &operator ++(Complex &a) { a.real++; a.image++; return a; } Complex operator ++(Complex &a,int) { Complex t=a; a.real++; a.image++; return t; } int main() { Complex a(1,2),b(3,4),c,x; c=a+b; c.print(); x=++c; x.print(); x=c++; x.print(); c.print(); }
Operation results:
Special operator overloading (can only be implemented with member functions)
Type conversion function
Converts the current object to another type of object.
- < class name >:: operator < type > ()
- Multiple conversion functions can be defined in a class, each < type >.
- The function has no formal parameters and does not specify a return value.
- However, a < type > object or value should be returned in the body of the function.
//Special operator overloading //Type conversion function #include<iostream> using namespace std; class Int{//The I here is capitalized, which is different from the int integer keyword int x; public: Int(int a=0){ x=a; } operator int(){ return x; } }; int main() { Int a=5; int b; b=a; //b=(int)a;// Equivalent representation //b=int(a);// Equivalent representation b=a.operator int(); //Equivalent representation cout<<b<<endl; }
Operation results:
subscript operator
< return type > < class name >:: operator [] (< formal parameter >)
- The formal parameter is often an int type or other types, as long as it can correspond to an element.
- < return type > is often an object reference to serve as an lvalue of an expression.
- For the expression object [argument], the compiler converts it to object. operator [] (argument).
- Note that you can only handle one-dimensional arrays, not two-dimensional arrays.
#include<iostream> using namespace std; class IntVector{ int *iElem;//Used to point to the first element in the array int iUpper;//Used to record array size public: IntVector(int cElem):iElem(new int[cElem]),iUpper(cElem){}//Dynamically create an array of parameter sizes //And initialize iElem and iUpper with the address and size of the array respectively ~IntVector(){delete[] iElem;}//Destructor frees array space int& operator[](int index){//Subscript operator overloaded function //Returns the corresponding iElem subscript variable of type int when the subscript as a parameter does not exceed the bounds static int iErr=-1; if(index>=0&&index<iUpper) return iElem[index]; else { cout<<"Arrat bounds violation at"<<index<<endl; return iErr;//Take the subscript expression as an lvalue and change the current object. The return type of the function is reference } } }; int main() { IntVector v(10); int i; for(i=0;i<10;i++) v[i]=i; v[3]=v[9]; for(i=0;i<10;i++) cout<<"v["<<i<<"]="<<v[i]<<endl; return 0; }
Operation results:
Function call operator
< return type > < class name >:: operator() (< formal parameter table >)
- Like normal member functions, this function can take 0 or more formal parameters, but cannot take default values.
- < return type > can be an object or an object reference.
- For the expression object (argument table), the compiler processes it as object. Operator() (argument table).
- Can be used to access two-dimensional arrays.
//function call operator #include<iostream> using namespace std; class Point{ int x,y; public: Point(int x,int y):x(x),y(y){} Point &operator()(int dx,int dy){//Function call operators overload functions to achieve relative movement x+=dx; y+=dy; return *this;//The current object is used as the return value of the function and can be changed as an lvalue } void print() { cout<<"("<<x<<","<<y<<")"<<endl; } }; int main() { Point pt(1,2); pt(3,2).print(); pt(1,2).print(); return 0; }
Operation results: