catalogue
Static member
1. Declare static members: declare static variables in a class instead of defining them
class Person{ static int cnt;//Indicates that cnt belongs to the Person class, not the instantiated object static int getcnt(void){ return cnt; } }
2. Define and initialize static member variables: they need to be defined and initialized outside the class and outside the main function. The definition outside the main function is to complete the definition and initialization of static member variables before object instantiation
/* Defining and declaring static variables */ int Person::cne = 0;//It looks like a global variable, but it is actually a static member variable in the Person class
3. Non static member variables cannot be accessed in static functions
4. There are two methods to call member variables
1) Direct call
int main() { Person::getcnt(); }
2) Called by object
int main() { Person per per.getcnt(); }
demo
#include <iostream> #include <string.h> #include <unistd.h> using namespace std; class Person{ char *name; int age; char *work; static int cnt;/*Declare static variable members*/ public: static int getCount(){ return cnt; } Person(){ name = NULL; work = NULL; cnt++; } Person(char* name){ /*Open up a space to store names, but the space in the subroutine needs to be released by ourselves*/ this->name = new char[strlen(name)+1]; strcpy(this->name,name);//Put the parameter name into the open space this->work = NULL;//If there is no work parameter, a null value should be assigned to it, otherwise a segment error will occur in the destructor cnt++; } Person(char* name, int age, char* work = "none"){ cout<<"Person(char*, int)"<<endl; this->name = new char[strlen(name)+1]; strcpy(this->name,name); this->work = new char[strlen(work)+1]; strcpy(this->work,work); this->age = age; printfInfo(); cnt++; } Person(Person &per){//copying functions cout<<"Person(Person &)"<<endl; this->name = new char[strlen(per.name)+1]; strcpy(this->name,per.name); this->work = new char[strlen(per.work)+1]; strcpy(this->work,per.work); this->age = per.age; cnt++; } ~Person(){//Destructor, which helps to release resources before jumping out of the program (such as closing files, freeing memory, etc.). cout<<"~Person()"<<endl; if(this->name){ cout<<"name ="<<name<<endl; delete this->name; } if(this->work){ cout<<"work ="<<work<<endl; delete this->work; } } void printfInfo(){ cout<<" name = "<<name<<" age = "<<age<<"work = "<<work<<endl; } }; int Person ::cnt = 0;//Defining and initializing static variable members int main(int argc, char** argv) { Person per; Person per1; Person per2; Person per3; Person per4[100]; cout<<"Person cnt = "<<Person::getCount()<<endl; return 0; }
zhaohaip@ubuntu:~/c++_project/06_static$ ./project Person cnt = 104
Friend function
Declare friend function
friend class name function name ()
friend Point add(Point &p1, Point &p2);
demo
#include <iostream> using namespace std; class Point{ private: int x; int y; public: Point(){} Point(int x, int y):x(x), y(y){} void printInfo() { cout<<"("<<x<<","<<y<<")"<<endl; } friend Point add(Point &p1, Point &p2);//Set the member function as a friend function }; Point add(Point &p1, Point &p2) { Point n; n.x = p1.x+p2.x; n.y = p1.y+p2.y; n.printInfo(); } int main(int argc, char **argv) { Point p1(1,2); Point p2(2,3); add(p1,p2); }
book@100ask:~/c++_project/07_friend$ g++ main2.cpp book@100ask:~/c++_project/07_friend$ ./a.out (3,5)
operators overloading
1. What is the definition of operator overloading?
The operation process of changing operators is called operator overloading.
2. Why does operator overloading also reflect polymorphism?
First of all, the difference between "+", "-", "*", "/" and other operations of various data types lies in the different operation processes. Different data types correspond to different operation processes, which precisely reflects the polymorphism of the operation process, that is, the polymorphism.
3. What are the types of operator overloading?
Operator overloads are divided into ordinary operator overloads ("+", "-", "*", "/"), pre operator overloads ("+", "-"), post operator overloads ("+", "-"), insert operator overloads (">"), and extract operator overloads ("< <")
4. What are the ways to overload operators?
(1) make the operator overload function as the member function of the class
(2) make the operator overload function as the friend function of the class
When we need to add and subtract, we can directly
int a; int b; int c = a+b;
And a+b is actually a function. However, in the point class, such addition and subtraction are not allowed. Therefore, operator overloading is required.
Define overloaded operator (+) function:
Point operator+(Point &p1, Point &p2) //Class name operator operator (parameter)
demo
#include <iostream> using namespace std; class Point{ private: int x; int y; public: Point(){} Point(int x, int y):x(x), y(y){} void printInfo() { cout<<"("<<x<<","<<y<<")"<<endl; } friend Point add(Point &p1, Point &p2); friend Point operator+(Point &p1, Point &p2); }; Point add(Point &p1, Point &p2) { Point n; n.x = p1.x+p2.x; n.y = p1.y+p2.y; n.printInfo(); } Point operator+(Point &p1, Point &p2) { cout<<"Point operator+(Point &p1, Point &p2)"<<endl; Point n; n.x = p1.x+p2.x; n.y = p1.y+p2.y; return n; } int main(int argc, char **argv) { Point p1(1,2); Point p2(2,3); //p1+p2 is not allowed. You need to use operator overloading to add and subtract in the point class add(p1,p2); cout<<"****************"<<endl; Point sum = p1+p2; sum.printInfo(); }
Operation results
zhaohaip@ubuntu:~/c++_project/08_operator$ ./project (3,5) **************** Point operator+(Point &p1, Point &p2) (3,5)
Realize p + + and + + p through code
Note: since the overloaded function names of operators of p + + and + + p are the same, we need to distinguish them. This is equivalent to function overloading, which uses the same function name to realize different functions through different function parameters. The operator overload of p + + will have one more parameter than that of + + p. this parameter will not be used, but is only used to distinguish.
demo
#include <iostream> using namespace std; class Point{ private: int x; int y; public: Point(){ cout<<"Point()"<<endl; } Point(int x, int y):x(x), y(y){ cout<<"Point(int x, int y)"<<endl; } ~Point(){ cout<<"~Point()"<<endl; } Point(Point &p){ cout<<"Point(Point &p)"<<endl; x = p.x; y = p.y; } void printInfo() { cout<<"("<<x<<","<<y<<")"<<endl; } friend Point operator++(Point &p); friend Point operator++(Point &p,int a); }; /* Implement p1++ */ Point operator++(Point &p,int a) { cout<<"p++"<<endl; Point n; n = p; p.x += 1; p.y += 1; return n; } /* Implement + + p */ Point operator++(Point &p) { cout<<"++p"<<endl; p.x += 1; p.y += 1; return p; } int main(int argc, char **argv) { Point p1(1,2); cout<<"begin"<<endl; p1++; cout<<"******************"<<endl; ++p1; cout<<"end"<<endl; }
zhaohaip@ubuntu:~/c++_project/08_operator$ ./project Point(int x, int y) begin p++ Point() ~Point() ****************** ++p Point(Point &p) ~Point() end ~Point()
This kind of code has disadvantages. Through the running results, we can know that when executing + + p, we call the point (point & p) reference copy for no reason, and refer to the destructor more than once, which greatly affects our efficiency. We can change the return type of the function reloaded by the + + p operator, so that the return & reference type will be different
/* Implement + + p */ Point &operator++(Point &p) { cout<<"++p"<<endl; p.x += 1; p.y += 1; return p; }
zhaohaip@ubuntu:~/c++_project/08_operator$ ./project Point(int x, int y) begin p++ Point() ~Point() ****************** ++p end ~Point()