catalogue
1, Understanding of class
2, Access qualifier and encapsulation of class
3, Scope and instantiation of class
4, Calculation of object size of class
5, this pointer of class member function
6, Constructor
7, Destructor
8, Copy constructor
9, Operator overloading
10, Implementation of date class
Get the number of days per month
Create constructor
Compare date size
Date + - Days
Front + +, --, rear + +--
Date - date
Ask how many days a day is a day of the week
Overload input / output operators
11, const member
12, explicit keyword
13, static member
14, A new method of member initialization in C++11
15, Friends
16, Inner class
1, Understanding of class
Process oriented:
C language is process oriented, focusing on the process, analyzing the steps to solve the problem, and gradually solving the problem through function call
object-oriented:
C + + is based on object-oriented and focuses on objects. It divides a thing into different objects and completes it by the interaction between objects
For example, design a simple takeout system
Process oriented: focus on the process of placing orders, receiving orders, delivering meals, etc. Code to function level
Object oriented: focus on the implementation of class objects and the relationship between class objects, users, businesses, riders and the relationship between them. Reflected in the code level -- the design of classes and the relationship between classes
Class introduction
In C, the struct can only define variables, while in C + +, the struct can define variables and functions
This is because C + + is compatible with C, so the structure defined by struct can also define functions
Class definition
In C + +, a new concept of this structure is introduced, which is called class, and the keyword is class
class name
{class body};
Note: like the structure, don't forget the semicolon (;) at the end
Class body can store member variables and member functions
Note: if a function is defined in a class, the compiler may treat it as an inline function. Generally, it puts the declaration of the member function and defines the member function outside the class
2, Access qualifier and encapsulation of class
Access qualifiers: public, private, protected
Members decorated with public can be accessed directly outside the class
Protected and private modified members cannot be accessed directly outside the class (protected and private are similar here)
The scope of access rights starts from where the access qualifier appears until the next access qualifier appears
If there is no access qualifier, the scope ends with the} class
The default access permission of class is private and struct is public (because struct is compatible with C)
encapsulation
Concept: organically combine data and methods of operating data, hide the attributes and implementation details of the object, and only expose the interface to interact with the object
Because of encapsulation, member variables are generally placed in private and member functions in public
3, Scope and instantiation of class
Scope of class
Class defines a new scope and defines members outside the class. You need to use the:: scope resolver to indicate which class domain the members belong to
Class instantiation
Concept: the process of creating objects with class types is called class instantiation
Class is just a model that defines which members there are, but does not allocate actual space to store it
Class is similar to the structure in C language, except that one is to create structure variables and the other is to create objects. The instantiated objects occupy the actual physical space and store class member variables. As shown in the figure below, d1 is an object and the following is to access member functions
Class instantiates an object, just like building a house with architectural design drawings in reality, and class is like design drawings
4, Calculation of object size of class
For classes, only member variables are saved, and member functions are stored in public code segments. Therefore, when calculating the size of a class or object, only member variables are used
Conclusion: to calculate the size of a class or class object, only look at the member variables and consider the memory alignment. The C + + memory alignment rules are consistent with the C structure
The space occupied by an empty class is the same as that of a class with only member functions, and 1 byte will be given. This 1 byte does not store valid data, but only for space occupation, indicating that the object exists
5, this pointer of class member function
As can be seen from the above figure, d1 and d2 are the same Print function called
There is no distinction between different objects in the function body. When d1 calls the Print function, how does the function know that d1 object should be set instead of d2 object?
The C + + compiler adds a hidden pointer parameter to each "non static member function" so that the pointer points to the current object. The operation of all member variables in the function body is accessed through the pointer, which is the hidden this pointer
In fact, the calling member function should be as shown in the figure above, but this is hidden
Characteristics of this pointer
Type of this pointer: class type * const
It can only be used inside the "member function", but generally, it will not be displayed as follows
This pointer is essentially a formal parameter of a member function. When an object calls a member function, the object address is passed to this parameter as an argument. The declared formal parameter this cannot be displayed
This pointer is the first implicit pointer parameter of a member function. It cannot be displayed or passed to this
Note: this pointer is usually stored on the stack. Some compilers will put it in registers, such as vs2013 and ecx
normal operation
Run crash
analysis:
Although P is a null pointer, it will not compile and report an error when p calls the member function, because the null pointer is not a syntax error and the compiler cannot check it
Although P is a null pointer, there will be no null pointer access when p calls the member function, because the member function does not exist in the object
Here, p is passed as an argument to the hidden this pointer
6, Constructor
Concept: the constructor is a special member function with the same name as the class name. It is automatically called by the compiler when creating a class type object. It is called only once in the life cycle of the object. Its main function is to initialize the object, not to create an object in an open space
characteristic
The function name is the same as the class name
No return value
When an object is instantiated, the compiler automatically calls the corresponding constructor
Constructors can be overloaded
Date d1; // Call the parameterless constructor, which cannot be followed by parentheses, otherwise it is the function declaration
Date d2 (2015, 1, 1); // Call the constructor with parameters
If the constructor is not explicitly defined in the class, the C + + compiler will automatically generate a parameterless default constructor. Once the user explicitly defines the constructor, the compiler will no longer generate it
Member variables of built-in types (basic types: char, int, double, etc.) are not initialized
For a member variable of a custom type, it will call its default constructor for initialization. If there is no default constructor, an error will be reported
Default constructor: full default, no parameters. We don't write the constructor generated by the compiler by default
Both parameterless constructors and fully default constructors are called default constructors, and there can only be one default constructor
Although the parameterless constructor and the full default constructor are function overloads from the syntax, there is ambiguity in the call
For the convenience of distinguishing, as shown in the figure above, for example, the formal parameter is year and the member variable is_ Year, add one at the beginning_
Note: global objects are constructed before local objects
On constructor
The previous constructors are initialized in the function body. The statements in the constructor body can only be called initial value, not initialization. Because initialization can only be initialized once, and the constructor body can be assigned multiple times
Initializing list initializing member variables
Initialization list - where member variables are defined
Class name (parameter) colon (:) member variable (formal parameter or constant) comma (,) member variable (formal parameter or constant)
be careful:
Each member variable can only appear once in the initialization list (initialization can only be initialized once)
Class contains the following members, which must be placed in the initialization list for initialization
Reference member variable
const member variable
Custom type member (this class has no default constructor)
Reason: the above three variables must be initialized at the time of definition, otherwise an error will be reported during compilation. Member variables of other types can be initialized anywhere, such as int year, int month, etc
Try to use the initialization list for initialization, because no matter whether you use the initialization list or not, for custom type member variables, you will use the initialization list first
The declaration order of a member variable in a class is its initialization order in the initialization list, regardless of its order in the initialization list, as shown in the following figure
7, Destructor
Concept: when the object is destroyed, it will automatically call the destructor to clean up some resources of the class
characteristic
The destructor name is preceded by a character in the class name~
No parameter, no return value
A class has only one destructor. If not explicitly defined, the system will automatically generate the default destructor
At the end of the object life cycle, the C + + compilation system automatically calls the destructor
Similar to the default constructor generated by the compiler, the built-in type member variable is not processed, and the destructor of the custom type member variable is called back
For the space requested on the heap, you have to add free to the destructor and set the pointer to nullptr, as shown in the following figure
The constructor that first calls will be destructed after the meeting, and the constructor after that will be destructed.
Local objects are destructed first and global objects are destructed later. If a static object is local, it destructs first and then local objects
8, Copy constructor (special member function)
Concept: there is only a single formal parameter, which is a reference to the object of this class type (commonly used const decoration). It is automatically called by the compiler when creating a new object with an existing class type object
features
Copy constructor is an overloaded form of constructor
There is only one parameter of the copy constructor, and the parameter must be passed by reference. Using the value passing method will cause infinite recursive calls
Because to call the copy structure, you need to pass the parameters first, and the value and parameter transfer is a copy structure. To call the copy structure, you need to pass the parameters first, and the value and parameter transfer is a copy structure, which will be called infinitely recursively
If the definition is not displayed, the system generates the default copy constructor
Built in type members, which will complete the copy in byte order (shallow copy)
A custom type member will call its copy construct
9, Operator overloading
In order to enhance the readability of the code, C + + introduces operator overloading, which is a function with a special function name
Return type + operator + operator to be overloaded (>, <, +) + parameter list
be careful
You cannot create a new operator by concatenating other symbols: for example, operator @
Overloaded operators must have an operand of class type or enumeration type
The meaning of operators used for built-in types cannot be changed. For example, the meaning of built-in integer +
When an overloaded function is a class member, its formal parameters appear to be 1 less than the number of operands. The operator of the member function has a default formal parameter this, which is limited to the first formal parameter
Defined in class
The definition is global. Pay attention to ensure that the members of the class are accessible, otherwise an error will be reported in the compilation (private members are not accessible)
Because the member function of the class will have a hidden this pointer, there will be one less parameter than the global
.* ,:: ,sizeof ,?: ,. Note that the above five operators cannot be overloaded (note that. *, not *)
The difference between copy construction and assignment overload
Copy construction: copy and initialize an existing object, and create an instantiated object immediately
Assignment overload: copy assignment between two existing objects
For assignment overload, it is better to use reference return, and copy structure will appear in value passing copy
The compiler generates assignment overloads by default, which is similar to what copy constructs do
Built in type members will complete byte order value copy - shallow copy
A custom type member variable will call its operator=
10, Implementation of date class
Get the number of days per month
First, create a static array, and then take the number of days of each month as the size of each element. It is best to create an array of 13 elements. In this way, the first element is assigned a 0, and the other elements are assigned according to the talent value of each month, that is, arr[1]=31,arr[2]=28
Because the number of days in February changes, we have to consider ordinary years and leap years. The number of days in leap years is + 1
Create constructor
Here, the default value method is used to initialize the member variable
Note: only one of the declarations and definitions can have a default value. If it exists at the same time, an error will be reported
At the same time, we have to judge whether the date is legal. If not, explain it and print the date
Compare date size
There are 6 operators in total, namely >, <, > =, < =,! =, = =, Just write > and = =, and the rest can be reused
Overloading the > operator
First, judge the size of the year. d1 is true
If the years are equal, judge the months
If the year and month are equal, judge the day
In addition to the above three cases, it is d2 large
Overloading = = operator
When the month, year and day are equal, they are equal, so use & & connection
For example, overloading the > = operator can be written as d1 > d2 or d1 = = d2
Date + - Days
Date + = days
First + = days
Then judge_ Is day greater than the number of days in that month
If it is greater than the number of days in that month, subtract the number of days in that month, month + 1
If month + 1 is followed by 13, that year will be + 1 and month will be assigned as 1
Finally, * this is returned, and the copy structure can be reduced by passing reference
Date - = days
First - = days
Then judge_ Is day < = 0
Enter the cycle, first month-1, then judge whether the month is 0, 0, year-1, and the month is assigned as 12_ day + days of that month
It's better to return * this and use reference return to reduce parameters
Date + days
First, you have to create a temporary date variable, because you can't change the original object and use the copy structure
Then reuse the previous + = days for ret
Date - Days
Same as date + days
Note: date + - days cannot be returned by reference because it is a temporary variable
Front + +, --, rear + +--
Front++
Pass reference return to reduce copy structure
Postposition++
You have to create a temporary variable because post + + is used first and then++
Post + + has more int type parameters than pre + +, which is to distinguish between pre + + and post + +, and can only be int, which is specified by C + +
Pre -- and post -- the same
Date - date
First create a temporary variable for two dates. The initial default * this is larger and d2 is smaller
So create another variable of type int and assign a value of 1. The default value is * this > D2
Then compare * this and d2. If they are different from the initial default, they will be reversed and the flag will be - 1
Then use the while loop to judge if max is not equal to min, and jump out of the loop if it is equal. The number of days in the loop is + 1 and min+1
It is best to return the product of days and flag, which means that the subtraction is positive or negative
Ask how many days a day is a day of the week
You need to find a reference date. Here is January 1, 1900, which happens to be Monday, which is convenient for processing
Then create a pointer array with 7 elements, representing Monday to Sunday
Reuse the previous date date, and then use its return value% 7
Overload input / output operators
Overload output operator
Note: the function that overloads the output operator cannot become a member function of the class, because the first parameter of the member function is the this pointer, that is, the first operand of <. If it is a member function, it must be written as D1 < < cout, which obviously does not meet our expectations, so we have to define this function as a global function
The void return type is not used here because if it is continuously output, the void return cannot achieve the purpose, such as cout < < D1 < < D2
The same is true for input operator overloading, except that const cannot be added to the object
11, const member
As shown in the figure above, the object modified by const cannot call the member function Print(), because the implicit this pointer is involved, and the formal parameter is
A* const this: the argument is modified by const to enlarge the permission, so the compilation reports an error. Because this is hidden, const cannot be added to the parameter, so there is const modified member function
For the address (&), there is no need to overload, because the compiler will generate the overload of the default address. Overload is only required in special cases, such as to let others get the specified content
Summary: it is good to add const to member functions. It is recommended to add const if possible, so that ordinary objects and const objects can be called. However, if you want to modify the member function of member variables, you can't add const
12, explicit keyword
Modifying the constructor with explicit will prohibit the implicit conversion of single parameter constructor, as shown in the following figure
13, static member
Concept: class members declared as static are called static members of the class, and member variables modified with static are called static member variables; The member function modified with static is called static member function
characteristic
Static members are shared by all class objects and do not belong to a specific instance. For example, the static member variable count is initialized to 0. In object d1, it is added once to 1. In object d2, it is still 1 and will not be 0
Static member variables must be defined and initialized outside the class without adding the static keyword
Class static members are available class names: static members or objects Static members to access
Static member functions have no hidden this pointer and cannot access any non static members. They can only access static member variables and static member functions, but non static member functions can call static member functions
Like ordinary members of a class, static members have three access levels: public, protected and private, and can also have return values
14, A new method of member initialization in C++11
C++11 supports the initialization and assignment of non static member variables during declaration. The purpose is to solve the problem of calling its default constructor initialization for user-defined variables before, and make a patch instead of dealing with built-in types
Note: here is the default value for the declared member variable, not initialization!
15, Friends
Friends are divided into friend functions and friend classes
Disadvantages of friends: increase the coupling degree, destroy the package, and should not be used more
friend function
A friend function can directly access the private members of a class. It is an ordinary function defined outside the class and does not belong to any class, but needs to be declared inside the class. When declaring, you need to add the friend keyword
Friend functions can access private and protected members of a class, but not member functions of a class
Friend functions cannot be modified with const
Friend functions can be declared anywhere in the class definition and are not limited by the class access qualifier
A function can be a friend function of multiple classes
The calling principle of friend function is the same as that of ordinary function
Friend class
All member functions of a friend class can be friend functions of another class and can access non-public members of another class
Friend relations are unidirectional and not exchangeable
For example, if class A and class B declare class B as its friend class in class A, you can directly access the private member variables of class A in class B, but you can't access the private member variables of class B in class A
Friend relationship cannot be passed
If B is a friend of a and C is a friend of B, it does not mean that C is a friend of A
16, Inner class
Concept: if a class is defined inside another class, this inner class is called an inner class
The internal class B is basically the same as the global definition, except that it is limited by the external class a domain and is defined in the class domain of A
Internal class B is naturally a friend of external class A, that is, B can access a's private, and a cannot access B's private
characteristic
Internal classes can be defined in public, protected and private of external classes
The internal class can directly access the static and enumeration members in the external class without the object / class name of the external class
Sizeof (external class) = external class, which has nothing to do with internal class
//Header file #pragma once #include<iostream> using namespace std; class Date { friend ostream& operator<<(ostream& out,const Date& d); friend istream& operator>>(istream& in, Date& d); public: //Constructor Date(int year = 1970, int month = 1, int day = 4); //Find the number of days of each month int GetMonthDay(int _year, int _day)const; //Print date void Print() const; //Compare date size bool operator>(const Date& d2) const; bool operator<(const Date& d2) const; bool operator==(const Date& d2) const; bool operator>=(const Date& d2) const; bool operator<=(const Date& d2) const; bool operator!=(const Date& d2) const; //Find the date after how many days Date& operator+=(int day); Date operator+(int day) const; //How many days ago Date& operator-=(int day); Date operator-(int day) const; //Pre + +, post++ Date& operator++(); Date operator++(int); //Front and rear-- Date& operator--(); Date operator--(int); //How many days is the difference between the two dates int operator-(const Date& d2); //Date assignment Date& operator=(const Date& d2); //Ask for the day of the week void WeekDay(); private: int _year; int _month; int _day; }; //Definition file #include"date.h" int Date::GetMonthDay(int _year, int _month)const { static int arr[13] = { 0,31,28,31,30,31,30,31,31,30,31,30,31 }; int day = arr[_month]; if (_month == 2 && ((_year % 4 == 0 && _year % 100 != 0) || (_year % 400 == 0))) { day += 1; } return day; } void Date::Print() const { cout << _year << "-" << _month << "-" << _day << endl; } Date::Date(int year, int month, int day) { _year = year; _month = month; _day = day; if (!(_year > 0 && (_month > 0 && _month < 13) && (_day > 0 && _day <= GetMonthDay(_year,_month)))) { cout << "Illegal date" << endl; Print(); } } bool Date::operator>(const Date& d2)const { if (_year > d2._year) { return true; } else if (_year == d2._year && _month > d2._month) { return true; } else if (_year == d2._year && _month == d2._month && _day > d2._day) { return true; } else { return false; } } bool Date::operator<(const Date& d2)const { return !(*this >= d2); } bool Date::operator==(const Date& d2)const { return _year == d2._year && _month == d2._month && _day == d2._day; } bool Date::operator>=(const Date& d2)const { return *this > d2 || *this == d2; } bool Date::operator<=(const Date& d2)const { return !(*this > d2); } bool Date::operator!=(const Date& d2)const { return !(*this == d2); } Date& Date::operator+=(int day) { if (day < 0) { return *this -= -day; } _day += day; while (_day > GetMonthDay(_year, _month)) { _day -= GetMonthDay(_year, _month); ++_month; if (_month == 13) { _month = 1; ++_year; } } return *this; } Date Date::operator+(int day) const { Date ret(*this); ret += day; return ret; } Date& Date::operator-=(int day) { if (day < 0) { return *this += -day; } _day -= day; while (_day <= 0) { --_month; if (_month == 0) { _month = 12; --_year; } _day += GetMonthDay(_year, _month); } return *this; } Date Date::operator-(int day) const { Date ret(*this); ret -= day; return ret; } Date& Date::operator++() { *this += 1; return *this; } Date Date::operator++(int) { Date ret(*this); *this += 1; return ret; } Date& Date::operator--() { *this -= 1; return *this; } Date Date::operator--(int) { Date ret(*this); *this -= 1; return ret; } int Date::operator-(const Date& d2) { Date max = *this; Date min = d2; int flag = 1;//Default D1 > D2 if (*this < d2) { max = d2; min = *this; flag = -1; } int count = 0; while (min != max) { ++min; ++count; } return flag * count; } Date& Date::operator=(const Date& d2) { _year = d2._year; _month = d2._month; _day = d2._day; return *this; } void Date::WeekDay() { Date d(1900, 1, 1); const char* arr[7] = { "Monday","Tuesday","Wednesday","Thursday","Friday","Saturday","Sunday" }; int count = (*this) - d; cout << arr[count % 7] << endl; } ostream& operator<<(ostream& out, const Date& d) { out << d._year << "/" << d._month << "/" << d._day << endl; return out; } istream& operator>>(istream& in, Date& d) { in >> d._year>> d._month>> d._day; return in; } //Test file #include"date.h" void test1() { Date d1(2021, 2, 9); Date d2(2021, 2, 9); cout << (d1 > d2) << endl; cout << (d1 < d2) << endl; cout << (d1 <= d2) << endl; cout << (d1 >= d2) << endl; cout << (d1 == d2) << endl; cout << (d1 != d2) << endl; } void test2() { Date d1(2022, 1, 30); d1 += 1500; d1.Print(); Date d2(2020, 1, 15); d2 -= 1500; d2.Print(); } void test3() { //Date d1(2022, 3, 15); //Date d2(2016, 1, 19); //int ret = d1 - d2; //cout << ret; //cout << d1; //cout << d2; //Date d3; //cin >> d1; //cout << d1; //cout << d3; /*Date d1; cin >> d1;*/ /*Date d1; cin >> d1; cout << d1;*/ Date d1(2022, 2, 25); d1.WeekDay(); } int main() { //test1(); //test2(); test3(); return 0; }