About the operator overloading of C + + those things

Source: Internet
Author: User

C + + for some time, today suddenly to overload an operator, found himself a little forgotten, and then check the data to do a little summary of C + + operator overloading.

One, what is operator overloading

The overloads of the operators are specific to the C + + language, and Java does not have operator overloading, so operator overloading is likely to become a C + + high-frequency test-taker in a written interview. Operator overloading is the meaning of redefining operators, such as common +,-,x,÷ that can be overloaded. Operator overloading uses the keyword operator, which is expressed in the following form:

return value operator overloaded operator (function argument list)

To give a simple example, there is a fractional class, which is defined as follows:

Class Fraction{public:int x;//numerator int y;//denominator fraction (int x = 0,int y = 1): x (x), Y (y) {}        void Show () {cout << x <&l t; " /"<< y << Endl;}}
For example, the definition of two classes fraction fa,fb, you make a fa+fb must be wrong, because the compiler will prompt you + it does not know, but this score added in reality is a very reasonable thing. So we have to redefine the meaning of the + to meet the + use in this case. It should be defined in this way;

fraction operator+ (const fraction& fa,const fraction& FB)

So now we have to understand, when the compiler encountered FA+FB this situation, how the compiler to parse it? The rules for parsing are as follows:

met FA + FB two parsing rules, first go to the member function of the class to find a function operator+ (constfraction& fb), Find a global function in the global area. operator+ (constfraction& fa, const fraction& FB), which means that we can write the overloaded function as a member function, or as a form of global function, Blogger suggests that If you can write a member function, do not write a global function, and it is best to select only one scheme. The Red font section above is the global form of the + reload.

Knowing the above principle, we first take the global form of overloading.

Fraction addfraction (const fraction& fa,const fraction& fb) {fraction fc;fc.x = fa.x * fb.y + fa.y * fb.x;fc.y = FA . Y * Fb.y;return fc;//return fraction (fa.x * fb.y + fa.y * fb.x,fa.y * fb.y);//abbreviated}
/* the following code will provide a pair of fractional classes fraction The +,-, *,/overload */
/* operator overloading, operator overloading for fractional classes */#include <iostream>using namespace Std;class fraction{public:int x;int y; fraction (int x = 0,int y = 1): x (x), Y (y) {}/* The global function is not written as long as the member function can be written, when the compiler encounters the FA+FB, the first is FA, and then the + number so that is in order, that is, FA called the overloaded member function, So inside this is the FA object */fraction operator+ (const fraction& FB) {fraction c; cout << this->x << this->y << fb.x << fb.y << endl;c.x = this->x * fb.y + this->y * fb.x;c.y = this->y * Fb.y;return c;//r Eturn Fraction (this->x * fb.y + this->y * fb.x,this->y * fb.y);} /* The design member function completes the subtraction of two fractions */fraction operator-(const fraction& FB) {return fraction (this->x * fb.y-this->y * fb.x, This->y * fb.y);} /* The design member function implements two fractional multiplication */fraction operator* (const fraction& FB) {//can be designed as any return value type return fraction (THIS-&GT;X * fb.x,this- >y * fb.y);} /* Complete two fractions *=*/void operator*= (const fraction& FB) {this->x *= fb.x;this->y *= fb.y;} void Show () {cout << x << "/" << y << endl;}};/ * Design a function of fractional addition, the global form of overloaded *///fraction addfraction (const FRAction& fa,const fraction& fb) {///*fraction fc;//fc.x = fa.x * fb.y + fa.y * fb.x;//fc.y = fa.y * Fb.y;//return FC; *///return Fraction (fa.x * fb.y + fa.y * fb.x,fa.y * fb.y);//shorthand//}/* design a function to return a double to add a fraction and an integer */double operator+ (const FR action& Fa,int x) {Double c;c = x+1.0* (FA.X/FA.Y); cout << c << endl;return c;} void Main () {fraction FA (1,3); Fa.show (); Fraction FB (fb.show);//addfraction (FA,FB). Show (); Fraction FC = fb + fa;fc.show ()//cout << &addfraction (FA,FB);//This sentence illustrates what//fraction fd = Fa-fb;//fd.show ();//fr Action Fe = FA * Fb;//fe.show ();//fa *= fb;//fa.show ();/////////////////////double res = fb + 100;//cout << Res;}


Second, overloading of input and output stream operators <<,>>

Take an integer wrapper class as an example of the integer class

Class integer{
int data;
Public
Integer (int data = 0):d ata (data) {}

}

If the object is a custom class, cin >> fa,cout << FA also causes the compiler to give an error. Then you need to overload the two operators. In the previous section, we said that there are two types of parsing rules for overloaded operators, which are first found in the member functions of the class before the global overloaded functions are found. For example, the overloaded output stream operator >>, first go to the ostream type, find a member function called:operator<< (const integer& i), So let's think about it, can you find it? Ostream is a system-provided class, it is obviously very difficult for you to add such a member function to the Ostream class, so the output, the best form of the output operator is overloaded into global form.

/* Use global function overloading << operator */ostream& operator<< (ostream& os,const integer& i) {//If void as output does not support continuous output// return OS << i.data;os << i.data;return os;} /* Write your own input stream function >>*/istream& operator>> (istream& is,integer& i) {//Can not write const here, input is to change this object is > > I.data;return is;}

Iii. Some notes on operator overloading
Includes overloads of the two-tuple operator, overloading of unary operators, explicit overloaded rules, which operators can be overloaded, which ones are not, which can only be overloaded into members, and which can only be overloaded into global form.

Parsing rules for overloading of unary operators: first go to the A object to find a member function operator# (), if not found, go to global find a global function called operator# (a), #代表所需要重载的一元运算符, in the overloaded ++,--need to note, before + + and after + + The meaning of the representative is different, the effect is different, so it is overloaded separately, and whether it can be continuous + +, for example, + + (++a) This form.

/* overloads of several unary operators */#include <iostream>using namespace Std;class integer{int data;public:integer (int data = 0):d ata ( Data) {}/*! Overloading of Operators */integer operator! {return Integer (!data);//return!data; When a single parameter constructor appears in a type, there is a default type conversion}/*-,~,++,--operator overload */integer operator-() {return Integer (-data);} The overload of the/*++ operator, by default, is the former ++*/integer& operator++ () {//note, if the return is not a reference, what effect in the main function Data++;return *this;} /* Overload */const integer operator++ (int)//dummy {return integer (data++) for post-design + +;} Friend integer& operator--(integer& i); Friend Const Integer operator--(integer& i,int); Friend ostream& operator<< (ostream& os,const integer& i) {return OS << i.data;}};/ * Now consider overloading the global form before-and after--*/integer& operator--(integer& i) {I.data--;return i;} Const integer operator--(integer& i,int) {return Integer (i.data--);} int main () {Integer ia (+); cout <<!ia << endl;cout <<!!     ia<< endl;cout <<-ia << endl;cout << + + (++ia) << Endl; The return void does not support continuous ++cout <&Lt IA << Endl; cout << ia++ << Endl; In the absence of overload after + +, this sentence in Ubuntu is not able to pass, not supported after ++,vs can pass, but the result is not correct//reload after + + cout << ia++< < endl;//plus const can prevent continuous post-++cout << ia<< endl;/* so continuous after + + has no meaning, continuous after + + in C language is compiled, support continuous front ++*//* Global form of pre-post-overload */cout <<--ia<<endl;cout << ia << endl;cout << ia--<<endl;cout <& Lt ia<< Endl;}


Iv. Limitations of operator overloading

Operators that cannot be overloaded include

1,::( Scope )

2,. ( member operator )

3,. * member Pointer dereference

4. Sizeof (type size)

5,?: Ternary operators

6, Typeid gets the type of information (return value type TypeInfo )


Only existing operators can be overloaded, and new operators cannot be invented;

You cannot perform operator overloading on a base type (at least one of the types in an operator overload is non-basic);

You cannot change the operation characteristics of an operator; you cannot convert a dollar to two yuan;


Five, can only be overloaded into operator in the form of a member: = , [], () (preferably a member += , -= , /=  ,*,-> and so on.

The overloading of the assignment operator = is a bit cumbersome, because there must be memory operations involved, as well as the issue of dark-and-dark copies. Look at the code below.

#include <iostream>using namespace Std;class array{int size;     The actual size of the space used to record the last data, int len; Space size for marker allocation int *datas;public:explicit Array (int len = 5): Len (len), size (0) {//explicit prevent implicit conversion//allocation of memory Datas = new Int[len] ;} ~array () {delete[] Datas;datas = NULL;} Copy constructor Array (const array& arr) {//handle memory Independence size = Arr.size;len = arr.len;//request New Memory Datas = Neo int[len];for (int i = 0; I & Lt Size i++) {Datas[i] = arr.datas[i];}} void Push_data (int d) {if (size >= len) {///expansion expend (),//expend Why there is no predecessor declaration to invoke, remember that functions that operate within a class do not require a predecessor declaration}datas[size++] = d                       ;//If size is larger than pre-allocated space, the expansion operation is}void expend () {int *temp = datas;                    retention mechanism len = 2 * len + 1;datas = new Int[len]; Datas is reassigned to space for (int i = 0; i < size; i++) {datas[i] = temp[i];}                           Delete[] temp; Release the middle value, this process note}void Show () {if (0 = = size) {cout << "[]" << Endl;return;} for (int i = 0; i < size-1; i++) {cout << datas[i] << ', ';} cout << datas[size-1] << Endl;} //overloaded = operator array& operator= (const array& arr) {if (this = &arr) {//prevents assigning itself to itself size = Arr.size;len = Arr.len;int *te MP = datas;//re-request memory Datas = new int[len];//assignment data for (int i = 0; i < size; i++) {datas[i] = arr.datas[i];} Release your original memory delete[] temp;} return *this;} overloaded [] operator, according to subscript data int operator[] (int ind) const{//does not modify this object, you can add Constreturn datas[ind];}; void Main () {//array Arra = 20;//prevents implicit conversions, but compiles an Array arra;arra.push_data (9) If no explicit is added; Arra.push_data (5); Arra.push_data (2); Arra.push_data (7) cout << arra[0] << endl;cout << arra[10] << endl;//out of bounds// Array ARRB = Arra; This parsing method will find the copy constructor//arrb.show (); Array ARRB;ARRB = arra;//is parsed with operator overloading, and if no = overloads are provided, the system-provided byte-by-copy mode is arrb.show ();//The program is collapsed, is overloaded and will not error, and will not crash}

In the above code, if you encounter arrb= Arra and we do not provide an assignment operator overload, then the compiler will take the default processing, that is, byte-by-bit copy, then this copy method in the processing of datas heap memory What is the problem? The member variables such as Len,size,datas are overwritten in turn, then the heap memory pointed to by the ARRB member Datas is the same as the heap memory that Arra datas points to, then the heap memory pointed to by ARRB Datas is leaked. This is the more serious problem here.


Vi. overloading of the parentheses operator ()

We often like this when we write programs with int x = (int) y, where y is not an int type, this is a forced type conversion, but if we define a product class, it has the member int count represents the number of products, double Price stands for product prices, and if in development we want to convert this product to an int type, it is obvious that for developers we want to get the number of products. If we want to turn product into a double type, we certainly want to get the price.


Therefore, the overloading of parentheses is widely used in development, and its function is to convert a single parameter type into the current object type.


Syntax format: Since the parentheses can only be members, then we must think: int operator () () {}, but this is not possible, the compiler does not recognize that the overload of parentheses has a fixed format: operator type () {

Return Object type

}

If you want to overload the parentheses to return int, you have to write this:

operator Int () {

return count;

}

/* Overloading of the parentheses operator, converting a single parameter type to the current object type *//* parentheses operator overload *//*operator type () {return type Object}*/#include <iostream>using namespace Std;class product{int count;double price;public:product (int count = 0, double price = 0.0): Count (count), price (price) {}/* Overloaded () operator *///We generally write this way, the compiler does not recognize the//int operator () () {//return count;//}//but it has to be written in fixed form, not why operator Int () {return Count;} /* Convert parentheses to double */operator double () {return price;}}; int main () {Product product (100, 1.15);/* Now if we want to turn this Product into an integer, we want the quantity */int count = (int) product;cout << count << endl;double price = (double) product;cout << price << Endl;}


Vii. overloads of the new delete operator

The first thing to understand is that new and delete do things more than malloc and free.

if the member variable of a class is a class type, the member is automatically created and the constructor is called automatically.

Delete will call the destructor, and free will not.

#include <iostream>using namespace std;/* in this case if the C compiler asks sizeof (A) whose size is 0 and in C + + The compiler for SIZIOF (A) is 1. Here's how the compiler treats memory allocations, and I think these tiny points of knowledge show the quality of a good C + + program programmer */class a{public:a () {cout << "A ()" < < Endl; }~a () {cout << "~a ()" << Endl;}}; Class B{a A;public:b () {cout << "B ()" << Endl;} ~b () {cout << "~b ()" << Endl;}}; int main () {b* PB = static_cast<b*> (malloc (B)); b * Pb2 = new B (); free (pb);d elete Pb2;}

Reload New Delete:

fixed notation: void * operator new (size_t size) void operator delete (void * ptr)

#include <iostream> #include <cstdlib>using namespace Std;class date{int year;int month;int day;public:date (int year = 0, int month = 0, Int. day = 0): Year (year), month (month), day {cout << "Date ()" << Endl;} ~date () {cout << "~date ()" << Endl;}};/ * Put to the member and the global is the same */void* operator new (size_t size) {//has automatic recognition of the size of the function cout << "My operator new" << size << endl;re Turn malloc (size);} void operator delete (void* ptr) {cout << "operator delete" << endl;free (PTR);} int main () {date * date = new Date ();d elete date;}



About the operator overloading of C + + those things

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.