Article directory
- Knowledge points of function overloading
-
- Overview of function overloading:
- operator overloading
-
- plus operator overloading
- Increment operator overloading
- assignment operator overloading
- relational operator overloading
- function call operator overloading
- Experimental results of operator overloading
-
- The return value of a function cannot be used as a condition for function overloading
- References as conditions for function overloading
- Function overloading encounters default parameters
- Addition operator – use member function to overload the addition operator
- Addition operator – Overloading the addition operator using global functions
- Overloading of left shift operator
- Increment operator overloading
- Overloading of assignment operator
- Overloading of relational operators
- overloading of the function call operator
Knowledge points of function overloading
Overview of function overloading:
Function: the function name can be the same, improving reusability
Function overloading satisfies the conditions:
- under the same scope
- same function name
- Function parameter types are different, or the numbers are different or the order is different
Note: The return value of a function cannot be used as a condition for function overloading
#include <iostream> using namespace std; void fun() { cout << "this is a func" << endl; } void fun(int a) { cout << "this is a func(int a)" << endl; } int main() { fun(10); fun(); system("pause"); return 0; }
//Precautions:
//The return value of the function cannot be used as a condition for function overloading, which will be ambiguous
1. Precautions for function overloading
- References as overloaded conditions
#include <iostream> using namespace std; void fun(int & a) { cout << "this is a func(int & amp; a)" << endl; } void fun(const int & a) { cout << "this is a func(const int & amp; a)" << endl; } int main() { fun(10); int a = 10; fun(a); system("pause"); return 0; }
- Function overloading encounters default parameters
Because there are default parameters, when the function is called, it can be called without writing some parameters, which will cause the two functions to be ambiguous, try to avoid
#include <iostream> using namespace std; void fun(int a) { cout << "this is a func(int a)" << endl; } void fun(int a, int b = 10) { cout << "this is a func(int a,int b)" << endl; } int main() { fun(10, 20); //fun(10); Both functions can be called, resulting in ambiguity system("pause"); return 0; }
Operator overloading
Operator overloading concept: redefine existing operators and give them another function to adapt to different data types
Plus operator overloading
Function: realize the operation of adding two custom data types
Overloading the plus operator with member functions
#include <iostream> using namespace std; class Person { public: int m_A; int m_B; Person operator + (Person & p) { Person temp; temp.m_A = this->m_A + p.m_A; temp.m_B = this->m_B + p.m_B; return temp; } }; void text01() { Person p1; p1.m_A = 10; p1.m_B = 10; Person p2; p2.m_A = 10; p2.m_B = 10; Person p3 = p1 + p2; cout << p3.m_A << endl; cout << p3.m_B << endl; } int main() { text01(); system("pause"); return 0; }
Overloading the plus operator with a global function
#include <iostream> using namespace std; class Person { public: int m_A; int m_B; }; Person operator + (Person & amp; p1, Person & amp; p2) { Person temp; temp.m_A = p1.m_A + p2.m_A; temp.m_B = p1.m_A + p2.m_B; return temp; } void text01() { Person p1; p1.m_A = 10; p1.m_B = 10; Person p2; p2.m_A = 10; p2.m_B = 10; Person p3 = p1 + p2; cout << p3.m_A << endl; cout << p3.m_B << endl; } int main() { text01(); system("pause"); return 0; } 2. Left shift operator overloading #include <iostream> using namespace std; class Person { public: int m_A; int m_B; }; //ostream object can only be used by one, and only global functions can be used ostream & amp; operator<<(ostream & amp; cout, Person & amp; p) { cout << "m_A=" << p.m_A << " m_B= " << p.m_B; return cout; } void text02() { Person p; p.m_A = 10; p.m_B = 10; cout << p << endl; } int main() { text02(); system("pause"); return 0; }
Summary: Overloading the left shift operator with friends can output custom data types
Increment operator overloading
#define _CRT_SECURE_NO_WARNINGS 1 #include <iostream> using namespace std; class Integer { //friend ostream & amp; operator<< (ostream & amp; cout, const Integer & amp; temp); public: Integer() {} // Pre-increment operator overloading: Integer & operator ++ () { this->integer ++ ; return *this; } // Post-increment operator overloading: //Pay attention to the return value, not a reference Integer operator + + (int) { Integer temp = *this; this->integer ++ ; return temp; } //It is not a constant function, because the object passed in is const modified, so the formal parameter must also be const modified //The first formal parameter is the compiler's default this pointer, which cannot be written explicitly, so add a const after the parentheses to indicate that the modified this pointer void display() const { cout <<this->integer; } protected: private: int integer{}; }; ostream & amp; operator<< (ostream & amp; cout, const Integer & amp; temp) { //cout << "integer = " << temp.integer << endl; temp. display(); return cout; } //The output object is a class, which needs to overload the operator<< //ostream & amp; operator<< (ostream & amp; cout, const Integer & amp; temp) //{ // cout << "integer = " << temp.integer << endl; //} void test01() { Integer pinteger01; + + pinteger01; cout << ( + + pinteger01 ) << endl; cout << pinteger01 << endl; } void test02() { Integer pinteger02; pinteger02++; cout << pinteger02 + + << endl; cout << pinteger02 << endl; } int main() { test01(); test02(); system("pause"); return 0; }
// first call:
//Call the copy function -> the integer value of the original class + 1 -> return an object of the copied class
//Second call:
//Call the copy function (the integer value of the copied class has been self-incremented on the original basis) -> the integer value of the original class + 1 -> return an object of the copied class
Assignment operator overloading
#include <iostream> #include<string> using namespace std; class People { public: People(string name = "", int* ptr = NULL); // normal constructor, People(const People & amp; peo); //display declaration copy constructor ~People(); void Display(); void SetAge(int age); private: string m_name; int* mp_age; }; People::People(string name, int* ptr) { m_name = name; mp_age = ptr; } People::People(const People & peo) { this->m_name = peo.m_name; this->mp_age = new int(*peo.mp_age); //reapply for a piece of memory to store age, to avoid two objects using the same piece of memory } People::~People() { delete mp_age; // freeing memory multiple times without overloading the assignment operator will cause a crash. mp_age = NULL; } void People::Display() { cout << m_name << " is age " << *mp_age << endl; } void People::SetAge(int age) { *mp_age = age; } int main() { int* ptr = new int(10); string name = "Xiao Ming"; People people1 = People(name, ptr); People people2; people2 = people1; //Do not overload the assignment operator people1. Display(); people2. Display(); people1.SetAge(15); // modify people1 age people1. Display(); people2. Display(); system("pause"); return 0; }
Relational operator overloading
#include<iostream> using namespace std; #include<string> // Overloading relational operators class Person { public: Person(string name, int age) { m_name = name; m_age = age; } //Overload == number bool operator==(Person & p) { if (this->m_name == p.m_name & amp; & amp; this->m_age == p.m_age) return true; return false; } bool operator!=(Person & p) { if (this->m_name != p.m_name || this->m_age != p.m_age) return true; return false; } string m_name; int m_age; }; void test1() { Person p1("Tom", 18); Person p2("Tom", 18); if (p1 == p2) { cout << "p1==p2" << endl; } else { cout << "p1 and p2 are not equal!" << endl; } if (p1 != p2) { cout << "p1!=p2" << endl; } else { cout << "p1 and p2 are equal!" << endl; } } int main() { test1(); system("pause"); return 0; }
Function call operator overloading
#include <iostream> #include <string> using namespace std; // function call operator overloading //Print output class class MyPrint { public: // overloaded function call operator void operator()(string test) { cout << test << endl; } }; void MyPrint02(string test) { cout << test << endl; } void test01() { MyPrint myPrint; myPrint("hello world");//Because it is very similar to a function call, it is called a functor MyPrint02("hello world"); } //The functor is very flexible, there is no fixed way of writing //addition class class MyAdd { public: int operator()(int num1, int num2) { return num1 + num2; } }; void test02() { MyAdd myadd; int ret = myadd(100, 100); cout << "ret=" << ret << endl; // anonymous function object cout << MyAdd()(100, 100) << endl; } int main() { test01(); test02(); system("pause"); return 0; }
Experimental results of operator overloading
The return value of a function cannot be used as a condition for function overload
References as conditions for function overloading
Function overloading encounters default parameters
Addition operator – use member function to overload the addition operator
Addition operator – use global function to overload the addition operator
Overloading of left shift operator
Increment operator overload
Overloading of assignment operator
Overloading of relational operators
Overloading of the function call operator
Summary: Through this experiment, I have basically mastered the method of realizing polymorphism through operator overloading, learned the member function method and friend function method of operator overloading, and can basically distinguish the preposition and postposition of unary operators. Operator overloading is to give multiple meanings to existing operators, so that different types of data in the scope of an operator will lead to different behaviors. C++ provides a method for operator overloading, that is, operator overloading functions. The name of the function specifies The operator is followed by an overloaded operator. The overloaded operator function can make a new interpretation of the operator, that is, it can define various operations required by the user, but after the operator is overloaded, the original basic semantics remain unchanged, the priority of the operator is not changed, and the operation is not changed The associativity of the operator does not change the operands required by the operator, and cannot create a new operator. The priority and associativity are mainly reflected in the use of overloaded operators, and the number of operands is not only reflected in the overloading The use of operators is more related to the parameter setting when the function is defined. The functions of operators cannot directly operate on them, so we need to overload the operators. The actual meaning is to give operators new functions, so that they can operate on the classes and structures defined by ourselves. You can see the superiority of C++ through operator overloading, but because your foundation is not good enough, you should exercise more to become more familiar with C++.