VS C + + learning notes:
1. Getting to know C + +:
1.1 the first C + + program:
General framework:
#include <iostream> using namespace std; int main(){ system("pause"); return 0; }
Output hello world
#include <iostream> using namespace std; int main(){ cout << "hello world" << endl; printf("hello C++"); system("pause"); return 0; }
Summary: there are two output modes: cout < < xxxx "< < endl and printf. Cout... Endl can wrap lines automatically, while printf will not.
1.2 notes;
Function: add some instructions and explanations to the code to facilitate yourself or other programmers to read the code
Two formats:
- Single line comment: / / description
- Multiline comment: / * description information*/
The font after the comment is green
1.3 variables
Function: name a specified memory space to facilitate the operation of this memory
Syntax: data type variable name = initial value;
Example:
#include <iostream> using namespace std; int main(){ //Variable creation syntax: data type variable name = initial value; //For example: int a = 10; cout << "a = " << a << endl; system("pause"); return 0; }
1.4 constants
Function: used to record unchangeable data in the program
There are two ways for C + + to define constants:
- #Define macro constant: #define constant name constant value
- It is usually defined above the file to represent a constant
- Const modified variable: const data type variable name = initial value
- Usually, the keyword const is added before the variable definition, and the modification amount is constant and cannot be modified
Example:
#include <iostream> using namespace std; #define day 7 int main(){ cout << "One week:" << day << "day" << endl; const int month = 12; cout << "One year:" << month << "month" << endl; system("pause"); return 0; }
1.5 keywords
Function: keyword is a word (identifier) reserved in C + +
- Keywords cannot be used when defining variable or constant names
Keywords in C + + are as follows:
asm | do | if | return | typedef |
---|---|---|---|---|
auto | double | inline | short | typeid |
bool | dynamic_cast | int | signed | typename |
break | else | long | sizeof | union |
case | enum | mntable | static | unsigned |
catch | explicit | namespace | static_cast | using |
char | export | new | struct | virtual |
class | false | private | template | volatile |
const_cast | float | protected | this | wchar_t |
continue | for | public | throw | while |
default | friend | register | true | |
delete | goto | reinterpret_cast | try |
1.6 identifier naming rules
Function: when C + + specifies to name identifiers (variables and constants), it has its own set of rules
- Identifier cannot be a keyword
- The identifier can only be composed of letters, numbers and underscores
- The first character must be a letter or underscore
Suggestion: when naming an identifier, you'd better see the effect of knowing the meaning of the name to facilitate reading by yourself and others
2. Data type
C + + stipulates that when creating a variable or constant, you must indicate the corresponding data type, otherwise you cannot allocate memory to the variable
2.1 shaping
Function: integer variables represent the data of * * integer type * * *
There are several ways to represent integer types in C + +. The difference is that the memory space is different:
data type | Occupied space | Value range |
---|---|---|
Short (short integer) | 2 bytes | -215~215-1(-32768~32767) |
int (integer) | 4 bytes | -231-231 (about: - 2.1 billion ~ 2.1 billion) |
Long (long integer) | 4 bytes for Windows, 4 bytes for Linux 32, and 8 bytes for 64 | -231 ~ 231 (about:) |
longlong (long integer) | 8 bytes | -263~263 |
2.2sizeof function
Function: use sizeof function to count the memory size occupied by data type
Syntax: sizeof (data type / variable name)
Example:
#include <iostream> using namespace std; int main(){ int num = 10; cout << "int Length of type:" << sizeof(num) << endl; cout << "short Length of type:" << sizeof(short) << endl; system("pause"); return 0; }
2.3 real (floating point)
Function: used to represent decimals
There are two types of floating point variables:
- Single precision float
- Double precision double
The difference between the two is that the range of significant numbers is not used
data type | Occupied space | Significant digit range |
---|---|---|
float | 4 bytes | 7 significant digits |
double | 8 bytes | 15 ~ 16 significant digits |
2.4 character type
Function: character type variable is used to display a single character
Syntax: char variable name = 'character';
Note 1: when displaying character variables, use single quotation marks to enclose characters, not double quotation marks
Note 2: there can only be one character in a single quotation mark, not a string
- Character variables in C and C + + only occupy 1 character
- Character type variables do not store the character itself in memory, but put the corresponding ASCII value into the storage unit
2.5 escape characters
Function: used to represent some ASCII characters that cannot be displayed directly
Escape character | meaning | ASCII value (decimal) |
---|---|---|
\a | call the police | 007 |
\b | Backspace (BS) to move the current position to the previous column | 008 |
\f | Page feed (FF) moves the current position to the beginning of the next page | 012 |
\n | Line feed (LF) moves the current position to the beginning of the next line | 010 |
\r | Press enter (CR) to move the current position to the beginning of the line | 013 |
\t | Horizontal tabulation (HT) (skip to next TAB position) | 009 |
\v | Vertical tabulation (VT) | 011 |
\\ | Represents a backslash character '\' | 092 |
\' | Represents a single quotation mark | 039 |
\" | Represents a double quotation mark | 034 |
? | Represents a question mark | 063 |
2.6 string type
Function: used to represent a string of characters
Two styles
-
C style string:
Syntax: char variable name [] = "string value"
-
C + + style string:
Syntax: string variable name = "string value"
Note: header files are required when using C + + style strings: #include < string >
Example:
#include <iostream> #include <string> using namespace std; int main(){ char string1[] = "hello"; string string2 = "world"; cout << string1 << string2 << endl; system("pause"); return 0; }
2.7 boolean type bool
Function: Boolean data type represents true or false value
The bool type has only two values:
- True - true (essentially 1)
- False - false (essentially 0)
bool type takes up 1 byte
2.8 data input
Function: used to obtain data from the keyboard
Key words: cin
Syntax: CIN > > variable name
3. Operator
Function: used to execute code operations
There are mainly the following types of operators in C + +:
Operator type | effect |
---|---|
Arithmetic operator | Used to process four operations |
Assignment Operators | Used to assign the value of an expression to a variable |
Comparison operator | Used to compare expressions and return a true or false value |
Logical operator | Used to return true or false values based on the value of an expression |
3.1 arithmetic operators
Function: used to process four operations
Arithmetic operators include the following symbols:
operator | term | Examples | result |
---|---|---|---|
+ | Plus sign | +5 | 5 |
- | Symbol | -5 | -5 |
+ | plus | 10+5 | 15 |
- | reduce | 10-5 | 5 |
* | ride | 10*5 | 50 |
/ | except | 10/5 | 2 |
% | Mold taking (residual) | 10%3 | 1 |
++ | Pre increment | a=2;b=++a; | a=3,b=3 |
++ | Post increment | a=2;b=a++ | a=3,b=2 |
– | Pre decrement | a=2,b=–a | a=1,b=1 |
– | Post decrement | a=2,b=a– | a=1,b=2 |
Example:
#include <iostream> using namespace std; int main1() { int a,b; a = 5; cout << "a The value of is:" << a << endl; cout << "+a The value of is:" << +a << endl; cout << "-a The value of is:" << -a << endl; cout << "\n"; a = 10, b = 5; cout << "a The value of is:" << a << "b The value of is:" << b << endl; cout << "a+b The value of is:" << (a + b) << endl; cout << "a-b The value of is:" << (a - b) << endl; cout << "a*b The value of is:" << (a * b) << endl; cout << "a/b The value of is:" << (a / b) << endl; cout << "\n"; a = 10, b = 3; cout << "a The value of is:" << a << "b The value of is:" << b << endl; cout << "a%b The value of is:" << (a % b) << endl; cout << "\n"; a = 2, b = 0; cout << "a The value of is:" << a << "b The value of is:" << b << endl; b = ++a; cout << "implement b=++a after a The value of is:" << a << "b The value of is" << b << endl; cout << "\n"; a = 2, b = 0; cout << "a The value of is:" << a << "b The value of is:" << b << endl; b = a++; cout << "implement b=a++after a The value of is:" << a << "b The value of is" << b << endl; cout << "\n"; a = 2, b = 0; cout << "a The value of is:" << a << "b The value of is:" << b << endl; b = --a; cout << "implement b=--a after a The value of is:" << a << "b The value of is" << b << endl; cout << "\n" ; a = 2, b = 0; cout << "a The value of is:" << a << "b The value of is:" << b << endl; b = a--; cout << "implement b=a--after a The value of is:" << a << "b The value of is" << b << endl; system("pause"); return 0; }
3.2 assignment operator
Function: used to assign the value of an expression to a variable
The assignment operator includes the following symbols:
operator | term | Examples | result |
---|---|---|---|
= | assignment | a=5 | a=5 |
+= | Plus equals | a=5;a+=5 | a=10 |
-= | Minus equals | a=5;a-=5 | a=0 |
*= | Multiply equal | a=5;a*=5 | a=25 |
/= | Division equals | a=5;a/=5 | a=1 |
%= | Modulo equals | a=5;a%=2 | a=1 |
Example:
#include <iostream> using namespace std; int main(){ int a; a=5; cout << "implement a=5 in the future a The value of is:" << a << endl; a+=5; cout << "implement a+=5 in the future a The value of is:" << a << endl; a=5; a-=5; cout << "implement a-=5 in the future a The value of is:" << a << endl; a=5; a*=5; cout << "implement a*=5 in the future a The value of is:" << a << endl; a=5; a/=5; cout << "implement a/=5 in the future a The value of is:" << a << endl; a=5; a%=2; cout << "implement a%=2 in the future a The value of is:" << a << endl; system("pause"); return 0; }
3.3 comparison operators
Function: used to compare expressions and return a true or false value
Comparison operators have the following symbols:
operator | term | Examples | result |
---|---|---|---|
== | be equal to | 11,12 | 1,0 |
!= | Not equal to | 1!=1,1!=2 | 0,1 |
< | less than | 1<2,2<1 | 1,0 |
<= | Less than or equal to | 1<=1,2<=1 | 1,0 |
> | greater than | 1>2,2>1 | 0,1 |
>= | Greater than or equal to | 1>=2,1>=1 | 0,1 |
Example:
#include <iostream> using namespace std; int main(){ int a,b,c; a = 1,b = 2,c = 1; cout << "a The value of is: 1, b The value of is: 2, c The value of is: 1" << endl; cout << "expression a==c The results are:" << (a == c) << endl; cout << "expression a==b The results are:" << (a == b) << endl; cout << "expression a!=c The results are:" << (a != c) << endl; cout << "expression a!=b The results are:" << (a != b) << endl; cout << "expression a<b The results are:" << (a < b) << endl; cout << "expression b<a The results are:" << (b < a) << endl; cout << "expression a<=c The results are:" << (a <= c) << endl; cout << "expression b<=a The results are:" << (b <= a) << endl; cout << "expression a>b The results are:" << (a > b) << endl; cout << "expression b>a The results are:" << (b > a) << endl; cout << "expression a>=b The results are:" << (a >= b) << endl; cout << "expression a>=c The results are:" << (c >= a) << endl; system("pause"); return 0; }
Note: when using cout, you cannot directly output the results of comparison and algorithm. You should add parentheses to the expression first
3.4 logical operators
Function: used to return true or false values according to the value of the expression
Logical operators have the following symbols:
operator | term | Examples | result |
---|---|---|---|
! | wrong | !a | If a is true, the result is false; If a is false, the result is true |
|| | or | a||b | If one of a and b is true, the result is true; The result is false only if a and b are false at the same time |
&& | And | a&&b | Only when a and b are true at the same time, the result is true, otherwise it is false |
Note: in C and C + +, non-zero is true
#include <iostream> using namespace std; int main(){ int a,b,c; a=1,b=0,c=2; cout << "a The value of is 1, b The value of is 0,c The value of is 2\n implement!a The results are:" << (!a) << "implement!b The results are:" << (!b) << "implement!c The results are:" << (!c) << endl; cout << "implement a||b The results are:" << (a||b) << "implement a||c The results are:" << (a||c) << "implement b||0 The results are:" << (b||0) << endl; cout << "implement a||b The results are:" << (a||b) << "implement a||c The results are:" << (a||c) << endl; system("pause"); return 0; }
4. Procedure flow structure
c/c + + supports three basic program running structures: sequential result, selection structure and loop structure
- Sequence structure: the program is executed in sequence without jump
- Select structure: execute the corresponding code according to whether the conditions are met
- Loop structure: executes a piece of code multiple times according to whether the conditions are met
5. Array
5.1 general
An array is a collection of data elements of the same type
Feature 1: each data element in the array is of the same data type
Feature 2: the array is composed of continuous memory locations
6. Function
7. Pointer
7.1 const modifier pointer
const modifier pointer has three conditions:
-
Constant pointer const int * p
Features: the pointer can be modified, but the value pointed by the pointer cannot be modified
-
Pointer constant int * const p
Features: the value pointed by the pointer can be modified, but the pointer cannot be modified
-
Constant pointer constant cont int * const p
Features: the pointer and the value pointed by the pointer cannot be modified
7.2 pointers and arrays
Function: use pointer to access elements in array
Example:
#include <iostream> using namespace std; int main(){ int arr[10] = {0,1,2,3,4,5,6,7,8,9}; cout << "Value of the first element in the array:" << arr[0] << endl; int * p = arr; cout << "Access the first element with a pointer:" << *p << endl; //Traversing arrays with pointers for(int i = 0; i < 10; i++){ cout << *p; p++ } system ("pause"); return 0; }
7.3 pointers and functions
Function: use pointers as function parameters to modify the value of arguments
Example:
#include <iostream> using namespace std; void bubbleSort(int * arr,int len){ for(int i = 0;i<len-1;i++){ for(int j = 0;j<len-i-1;j++){ if(arr[j]>arr[j+1]){ int temp = arr[j]; arr[j] = arr[j+1]; arr[j+1] = temp; } } } return; } void printSort(int * arr,int len){ for(int i = 0; i < len ;i++,arr++){ cout << *arr << "<" ; } } int main(){ int arr[] = {4,6,9,2,1,3,8,7,0,5}; int len = sizeof(arr) / sizeof(arr[0]); bubbleSort(arr,len); printSort(arr,len); }
8. Structure
8.1 basic concept of structure
Structures are user-defined data types, allowing users to store different data types
8.2 definition and use of structure
Syntax: struct structure name {structure member list};
There are three ways to create variables through structures:
- struct structure name variable name
- struct structure name variable name = {member value...}
- Variables are created when a structure is defined
Example:
#include <iostream> #include <string> using namespace std; struct Student{ string name; int age; }s3; int main (){ struct Student s1; s1.name = "Zhang San"; s1.age = 18; cout << "full name:" << s1.name << "Age:" << s1.age << endl; struct Student s2 = {"Li Si",17}; cout << "full name:" << s2.name << "Age:" << s2.age << endl; s3.name = "Wang Wu"; s3.age = 19; cout << "full name:" << s3.name << "Age:" << s3.age << endl; system("pause"); return 0; }
Summary 1: when defining a structure, the keyword struct cannot be omitted
Summary 2: when creating structural variables, the keyword struct can be omitted
Summary 3: structural variables use the operator "." Access member
C + + core programming
This paper mainly introduces the C + + object-oriented programming technology in detail
1. Memory partition model
When executing a C + + program, the memory is divided into four areas:
- Code area: it stores the binary code of the function and is managed by the operating system
- Global area: store global variables, static variables and constants
- Stack area: it is automatically allocated and released by the compiler to store the parameter values and local variables of the function
- Heap area: it is allocated and released by the programmer. If the programmer does not release it, it will be recycled by the operating system at the end of the program
Meaning of four memory areas:
The data stored in different areas gives us different life cycles and gives us greater flexibility in programming
1.1 before program operation
After the program is compiled, an exe executable program is generated. Before the program is executed, it is divided into two areas
Code area:
Store the j machine instructions executed by the CPU
The code area is shared. The purpose of sharing is to have only one code in memory for programs that are frequently executed
The code area is read-only because it prevents the program from accidentally modifying its instructions
Global area:
Global and static variables are stored here
The global area also includes the constant area, where string constants and other constants are also stored
The data in this area is released by the operating system after the program j ends
Summary:
- In C + +, the program is divided into global area and code area before running
- The code area is characterized by sharing and read-only
- Global variables, static variables and constants are stored in the global area
- The constant area stores string constants and const modified global constants
1.2 after program operation
Stack area:
It is automatically allocated and released by the compiler to store the parameter values and local variables of the function
Note: do not return the address of the local variable, because the data opened up in the stack area is automatically released by the compiler
Stacking area:
It is allocated and released by the programmer. If the programmer does not release it, it will be recycled by the operating system at the end of the program
In C + +, new is mainly used to open up memory in the heap
1.3 new operator and delete operator
Using new operator in C + + to open up data in heap
The data developed in the heap area is manually developed by the programmer, manually released, and released by using the operator delete
Syntax: new data type
The data created with new will return the address of the data. You need to receive the return address with the pointer of the corresponding type
2. Reference
2.1 basic use of references
**Function: * * alias variables
Syntax: data type & alias = original name
2.2 notes for reference
- Reference must be initialized
- The reference cannot be changed after initialization
2.3 reference function parameters
**Function: * * when passing parameters to a function, you can use reference technology to make formal parameters modify arguments
**Advantages: * * pointer modification arguments can be simplified
Summary: the effect of referencing parameters is the same as that of address passing. The syntax of references is clearer and simpler
2.4 reference function return value
**Function: * * a reference can exist as the return value of a function
**Note: * * local variable reference cannot be returned
2.5 nature of reference
**Essence: * * the essence of reference is actually a pointer constant inside C + +
Conclusion: reference technology is recommended for C + + because of its convenient syntax. Reference is essentially a pointer constant, but all pointer operation compilers have done it for us
2.6 constant reference
**Function: * * constant reference is mainly used to modify formal parameters to prevent misoperation
In the function parameter list, const can be added to modify the parameter to prevent the parameter from changing the argument
3. Function improvement
3.1 function default parameters
In C + +, the formal parameters in the formal parameter list of a function can have default values
Syntax: function return type function name (parameter type parameter name = default) {}
be careful:
- If a location parameter has a default value, all parameters from this location must have a default value. Therefore, if you need to set the default value, the parameters are placed at the end of the function
- If the function declaration has a default value, it cannot have a default value when the function is implemented. On the contrary, if the function implementation has a default value, it cannot have a default value when the function is declared
3.2 function occupancy parameters
There can be placeholder parameters in the formal parameter list of functions in C + +, which are used for placeholder. This position must be filled when calling functions
Syntax: return function type function name (data type) {}
**Note: * * the placeholder parameter can also be set to the default value, for example: int func(int = 10) {}
3.3 function overloading
**Function: * * improve the reusability of functions
Function overload meets the following conditions:
- Under the same scope
- Same function name and type
- Function parameters have different types, numbers or orders
4 classes and objects
The three characteristics of C + + object-oriented are; Encapsulation, inheritance, polymorphism
C + + believes that everything is an object, and the object has its properties and behavior
For example:
People can be objects. Their attributes include name, age, height, weight... And their behaviors include walking, running, jumping, eating, singing
Objects with the same properties can be abstracted as classes
4.1 packaging
Encapsulation is one of the three characteristics of C + + object-oriented
4.1.1 significance of packaging:
- Take attributes and behaviors as a whole to express things in life
- Control attributes and behaviors with permission
Packaging significance I:
When designing classes, attributes and behaviors are written together to represent things
Syntax: class name {access rights: attribute / behavior};
**Example: * * design a student class. The attributes include name and student number. You can assign values to the name and student number, and display the student's name and student number
#include <iostream> using namespace std; class Student { public: string name; int student_ID; void Display_information() { cout << "full name:" << name << endl; cout << "Student No.:" << student_ID << endl; return; } }; int main() { Student s1; cin >> s1.name; cin >> s1.student_ID; s1.Display_information(); system("pause"); return 0; }
Note:
- The properties and behaviors in a class are collectively called members
- Properties are called: member properties member variables
- The behavior is called: member function member method
Packaging Significance 2:
Class can put properties and behaviors under different permissions when designing
There are three types of access rights:
1.public public permission member permission: it can be accessed within the class and can be accessed outside the class
2.protected protection permission member permission: you can access inside the class, you can't access outside the class, and your son can access the protected content in your father
3.private private permission member permission: you can access the private content inside the class, but not outside the class. Your son can't access the private content of your father
4.1.2 differences between struct and class
In C + +, the only difference between struct and class is that the default access permissions are different
difference:
- The default permission of struct is public
- class the default permission is private
4.1.3 set member property to private
**Advantage 1: * * set all member properties to private, and you can control the read and write permissions yourself
**Advantage 2: * * for write permission, we can check the validity of data
4.2 initialization and cleaning of objects
4.2.1 constructors and destructors
Object initialization and cleanup are also two very important security issues
An object or variable has no initial state, and the consequences of its use are unknown
Similarly, after using an object or variable, it will also cause some security problems if it is not cleaned up in time
C + + uses constructors and destructors to solve the above problems. These two functions will be automatically called by the compiler to complete object initialization and cleaning.
The initialization and cleaning of objects are what the compiler forces us to do. Therefore, if we do not provide constructs and destructors, the compiler will provide that the constructors and destructors provided by the compiler are empty implementations.
- Constructor: its main function is to assign value to the member attribute of the object when creating the object. The constructor is automatically called by the compiler without manual call
- Destructor: it is mainly used to call the system automatically before the object is destroyed to perform some cleaning work
Constructor syntax: class name () {}
- Constructor, no return value and no void
- The function name is the same as the class name
- Constructors can have arguments, so overloading can occur
- When the program calls the object, it will automatically call the construct without manual call, and it will only be called once
Destructor syntax: ~ class name () {}
- Destructor, no return value, no void
- The function name is the same as the class name, and the symbol is added before the name~
- Destructors cannot have parameters, so overloading cannot occur
- The program will automatically call the destructor before the object is destroyed, without manual call, and will only call it once
4.2.2 classification and calling of constructors
Two classification methods:
According to parameters, it can be divided into parametric structure and nonparametric structure
By type, it can be divided into ordinary structure and copy structure
Copy constructor syntax: function name (const class name & variable name)
Note: when copying the constructor, the function name needs to be the same as the class name
Three call modes:
Bracket method
Note: when calling the default constructor, you cannot add parentheses (), because the compiler will consider it as a declaration of a function and will not consider it as creating an object
Display method
Note 1: Person s2 = Person(10)Person(10) is an anonymous object. Features: after the current execution, the system will release and recycle the anonymous object immediately
Note 2: Person(s2) do not use the copy constructor to initialize anonymous objects. The compiler will think that Person(s2) == Person s2, which will cause redefinition of the object declaration
Implicit transformation method
Person q1 = 10 equals Person q1 = Person(10)
Person q2 = q1 equals Person q1 = Person(q1)
4.2.3 call timing of copy constructor
In C + +, there are usually three situations when copying constructor calls:
- Initialize a new object with an already created object
- Values are passed to function parameters
- Returns a local object as a value
4.2.4 constructor calling rules
By default, the C + + compiler adds at least three functions to a class
- Default constructor (no parameters, empty function body)
- Default destructor (no parameters, empty function body)
- The default copy constructor copies the values of attributes
Constructor calling rules are as follows:
- If the user defines a parameter constructor, C + + will no longer provide a default parameterless construct, but will provide a default copy construct
- If you define a copy constructor, C + + will not provide another constructor
4.2.5 deep copy and shallow copy
Shallow copy: a simple assignment copy operation
Deep copy: re apply for space in the heap area for copy operation
Summary: if the object properties are opened up in the heap area, you must provide your own copy constructor to prevent problems caused by shallow copy
4.2.6 initialization list
**Function: * * C + + provides initialization list syntax to initialize attributes
Syntax: constructor (): Property 1 (value 1), property 2 (value 2) {}
4.2.7 class objects as class members
A member in a C + + class can be an object of another class. We call it an object member instead of a member
Construction order: first call the construction of object members, and then call the construction of this class
The tectonic sequence is opposite to the tectonic sequence
4.3 C + + object model and this pointer
4.3.1 member variables and member functions are stored separately
In C + +, member variables and member functions in a class are stored separately
Only non static member variables belong to objects of a class
#include <iostream> using namespace std; class Person01 { }; class Person02 { public: int m_a; double m_b; //Non static member variables are on objects belonging to classes static int m_c; //Static member variables do not belong to class objects void func(){} //Non static member functions do not belong to class objects static void func01(){} //Static member functions do not belong to class objects }; int Person02::m_c = 0; void text01() { Person01 p; //Memory space occupied by empty objects: 1 //The C + + compiler will also allocate a byte space to each empty object to distinguish the memory occupied by empty objects //Each empty object should also have a unique space cout << "Person01 size of p = " << sizeof(p) << endl; return; } void text02() { Person02 p; cout << "Person02 size of p = " << sizeof(p) << endl; return; } int main() { text01(); text02(); system("pause"); return 0; }
4.3.2 this pointer concept
Each non static member function will only produce one function instance, that is, multiple objects of the same type will share a piece of code
C + + distinguishes itself from that object by providing a special object pointer, this pointer. The this pointer points to the object to which the called member function belongs
this pointer is a pointer implied in each non static member function
this pointer does not need to be defined and can be used directly
Purpose of this pointer:
- When a formal parameter has the same name as a member variable, it can be distinguished by the this pointer
- return *this can be used to return the object function in the non static member function of the class
4.3.3 null pointer accessing member functions
C + + hollow pointer can also call member functions, but you should pay attention to whether this pointer is used. If this pointer is used, it needs to be judged to ensure the executability of the code
4.3.4 const modifier member function
Constant function:
- After adding const to the member function, we call this function a constant function
- Member properties cannot be modified within a constant function
- After the keyword mutable is added to the member attribute declaration, it can still be modified in the function
Note: this pointer is equivalent to class name * const this, that is, pointer constant. Adding const modifier after member function is equivalent to const class name * const this pointer becoming constant pointer constant
Constant object:
- Add const before declaring an object to call it a constant object
- Constant objects only call constant functions
4.4 friends
The purpose of a friend is to let a function or class access private members in another class
The key to friendship: friend
Three implementations of friends:
- Global function as friend
- Class as friend
- Member function as friend
4.4.1 global functions as friends
Example:
#include <string> #include <iostream> using namespace std; class Building { friend void GoodGay(Building* building); public: Building() { this->m_SittingRoom = "a living room"; this->m_BedRoom = "bedroom"; } public: string m_SittingRoom; private: string m_BedRoom; }; void GoodGay(Building* building) { cout << "Accessing:" << building->m_SittingRoom << endl; cout << "Accessing:" << building->m_BedRoom << endl; } void text() { Building building; GoodGay(&building); } int main() { text(); system("pause"); return 0; }
4.4.2 making friends
Example:
#include <string> #include <iostream> using namespace std; class Building; class GoodGay; class GoodGay { public: GoodGay(); void show(); public: Building *m_building; }; class Building { friend class GoodGay; public: Building(); public: string m_SittingRoom; private: string m_BedRoom; }; Building::Building() { this->m_SittingRoom = "a living room"; this->m_BedRoom = "bedroom"; } GoodGay::GoodGay() { this->m_building = new Building; } void GoodGay::show() { cout << "Accessing:" << m_building->m_SittingRoom << endl; cout << "Accessing:" << m_building->m_BedRoom << endl; } void text() { GoodGay gg; gg.show(); } int main() { text(); system("pause"); return 0; }
4.4.3 member functions as friends
Example:
#include <string> #include <iostream> using namespace std; class Building; class GoodGay; class GoodGay { public: GoodGay(); Building* m_building; void show(); void show1(); }; class Building { friend void GoodGay::show(); public: Building(); string m_SittingRoom; private: string m_BedRoom; }; Building::Building() { m_SittingRoom = "a living room"; m_BedRoom = "bedroom"; } GoodGay::GoodGay() { m_building = new Building; } void GoodGay::show() { cout << "show Accessing:" << m_building->m_SittingRoom << endl; cout << "show Accessing:" << m_building->m_BedRoom << endl; } void GoodGay::show1() { cout << "show1 Accessing:" << m_building->m_SittingRoom << endl; } void text() { GoodGay gg; gg.show(); gg.show1(); } int main() { text(); system("pause"); return 0; }
4.5 operator overloading
Operator overloading concept: redefine the existing operators and give them another function to adapt to different data types
4.5.1 arithmetic operator overloading
**Function: * * realize the arithmetic operation of two user-defined data types
Example 1:
#include <iostream> using namespace std; class Preson { public: //Member functions implement plus operator overloading //Preson operator+(Preson& p) { // Preson temp; // temp.m_a = this->m_a + p.m_a; // temp.m_b = this->m_b + p.m_b; // return temp; //} void show() { cout << this->m_a << endl; cout << this->m_b << endl; } int m_a; int m_b; }; Preson operator+ (Preson &p1,Preson &p2) { Preson temp; temp.m_a = p1.m_a + p2.m_a; temp.m_b = p1.m_b + p2.m_b; return temp; } void text() { Preson p1; p1.m_a = 10; p1.m_b = 10; Preson p2; p2.m_a = 20; p2.m_b = 20; //Member function overload essence: Preson p3 = p1.operator+(p2); //Global function overload essence: Preson p3 = operator+(p1,p2); Preson p3 = p1 + p2; p3.show(); } int main() { text(); system("pause"); return 0; }
Example 2:
#include <iostream> using namespace std; class Preson { public: int m_a; int m_b; void show(); //Member functions implement multiplication function overloading //Preson operator*(Preson& p) { // Preson temp; // temp.m_a = this->m_a * p.m_a; // temp.m_b = this->m_b * p.m_b; // return temp; //} }; //The global function implements multiplication function overloading Preson operator*(Preson& p1, Preson& p2) { Preson temp; temp.m_a = p1.m_a * p2.m_a; temp.m_b = p1.m_b * p2.m_b; return temp; } void Preson::show() { cout << "m_a: " << this->m_a << endl; cout << "m_b: " << this->m_b << endl; } void text() { Preson p1; p1.m_a = 10; p1.m_b = 10; Preson p2; p2.m_a = 10; p2.m_b = 20; //Member function overload essence: Preson p3 = p1.operator*(p2); //Global function overload essence: Preson p3 = operator*(p1,p2); Preson p3 = p1 * p2; p3.show(); } int main() { text(); system("pause"); return 0; }
4.5.2 shift left operator overload
**Function: * * user defined data types can be output
Example:
#include <iostream> using namespace std; class Preson { friend ostream& operator << (ostream& cout, Preson& p); public: Preson(int a,int b); //Implement left operator overloading of member functions //ostream& operator << (Preson &p) { // cout << "m_a: " << this->m_a << "\nm_b: " << this->m_b; // return cout; //} private: int m_a; int m_b; }; Preson::Preson(int a,int b) { this->m_a = a; this->m_b = b; } ostream & operator << (ostream & cout, Preson & p) { cout << "m_a: " << p.m_a << "\nm_b: " << p.m_b; return cout; } void text() { Preson p1(10,20); //The essence of member function call: p.operator < < (ostream & cout), which cannot be realized. Cout is on the left and is generally not used //p1 << cout; //Essence of global function call: operator < < (ostream & cout, preson P) cout << p1 << "hello word" << endl; } int main() { text(); system("pause"); return 0; }
4.5.3 overloading of auto increment / Auto decrement operators
**Function: * * realize self increment and self decrement of user-defined data types
Example:
#include <iostream> using namespace std; class Preson{ friend ostream& operator<<(ostream& cout, Preson p); int m_a; int m_b; public: Preson(int a = 0, int b = 0); //Front overload //Preson& operator++() { // // this->m_a++; // return *this; //} //Post overload Preson& operator++(int) { Preson temp; temp = *this; this->m_a++; this->m_b++; return temp; } }; Preson::Preson(int a,int b) { this->m_a = a; this->m_b = b; } ostream& operator<<(ostream& cout, Preson p) { cout << p.m_a << "\t"; cout << p.m_b; return cout; } //Pre + + overload //void text01() { // // Preson p(0,0); // // cout << ++(++p) << "\nhello" << endl; // cout << p << endl; // //} void text2() { Preson p(0,0); //Because the post returns a value, chained programming cannot be used cout << p++ << endl; cout << p << endl; } int main() { //text01(); // Pre + + overload text2(); //Post + + overload system("pause"); return 0; }
4.5.4 overload of assignment operator
The C + + compiler adds at least four functions to a class
- Default constructor (no parameters, empty function body)
- Default destructor (no parameters, empty function body)
- The default copy constructor copies the values of attributes
- The assignment operator operator =, copies the value of the attribute
**Function: * * prevent the attribute in the class from pointing to the heap area, and the deep and shallow copy problem occurs during assignment operation
#include <iostream> using namespace std; class Preson { friend ostream& operator<<(ostream& cout, Preson &p); string m_name; int *m_age; public: Preson(string name,int age) { m_name = name; m_age = new int(age); } ~Preson() { if (m_age != NULL) { delete m_age; m_age = NULL; } } Preson & operator=(Preson &p) { m_name = p.m_name; if (m_age != NULL) { delete m_age; m_age = NULL; } m_age = new int(*p.m_age); return *this; } }; ostream & operator<<(ostream &cout, Preson &p) { cout << "full name:" << p.m_name << "\t Age:" << *p.m_age; return cout; } void text() { Preson p1("Tom", 18); Preson p2("Ros", 20); p2 = p1; cout << p1 << endl; cout << p2 << endl; } int main() { text(); system("pause"); return 0; }
4.5.5 overloading of relational operators
**Function: * * enables comparison between two user-defined data type objects
Example:
#include <iostream> using namespace std; class Preson { friend bool operator>(Preson &p1, Preson &p2); int m_age; public: Preson(int age) { m_age = age; } }; bool operator>(Preson &p1,Preson &p2) { if (p1.m_age > p2.m_age) { return true; } else { return false; } } void text() { Preson p1(18); Preson p2(20); if (p1 > p2) { cout << "p1 than p2 large" << endl; } else { cout << "p1 than p2 Small" << endl; } } int main() { text(); system("pause"); return 0; }
4.5.6 function call overload
- The function call operator () can also be overloaded
- Because the method used after overloading is very similar to the function call, it is called imitation function
- Imitation function has no fixed writing method and is very flexible
Example:
#include <iostream> using namespace std; class Preson { int m_age; public: void operator()(string str) { cout << str << endl; } int operator()(int a, int b) { return a + b; } }; void text() { Preson p1; p1("hello world"); cout << p1(1, 2) << endl; cout << Preson()(100, 100) << endl; //Anonymous function object Preson()("Tom"); //Anonymous function object } int main() { text(); system("pause"); return 0; }
4.6 succession
Inheritance is one of the three characteristics of object-oriented
There are special relationships between some classes, such as the following figure:
[the external chain image transfer fails. The source station may have an anti-theft chain mechanism. It is recommended to save the image and upload it directly (img-l0dlt0b6-1625882170002) (C: \ users \ admin \ appdata \ roaming \ typora user images \ 1603180073902. PNG)]
We found that when defining these classes, the lower level members not only have the commonalities of the upper level, but also have their own characteristics
At this time, we can k consider using inheritance technology to reduce duplicate code
4.6.1 basic syntax of inheritance
**Benefits of inheritance: * * reduces duplicate code
Syntax: class subclass: inheritance method parent class
Subclasses can also be called derived classes
A parent class can also be called a base class
Members in subclasses (derived classes) consist of two parts:
One is inherited from the parent class (base class), and the other is a member added by itself
The members inherited from the base class show their commonness, while the new members reflect their individuality
Example:
#include <iostream> using namespace std; Common implementation // //class Java { // //public: // void header() { // // Cout < < home page, open class, login, registration... (public header) < < endl; // } // // void footer() { // // Cout < < help center, communication and cooperation, station map... (public bottom) < < endl; // } // // void left() { // // Cout < < Java, C + +, Python, Php,... (public classification list) < < endl; // } // // void contert() { // // Cout < < Java subject video... "<< endl; // } // //}; // //class Python { // //public: // void header() { // // Cout < < home page, open class, login, registration... (public header) < < endl; // } // // void footer() { // // Cout < < help center, communication and cooperation, station map... (public bottom) < < endl; // } // // void left() { // // Cout < < Java, C + +, Python, Php,... (public classification list) < < endl; // } // // void contert() { // // Cout < < Python subject video... "<< endl; // } // //}; // //class Cpp { // //public: // void header() { // // Cout < < home page, open class, login, registration... (public header) < < endl; // } // // void footer() { // // Cout < < help center, communication and cooperation, station map... (public bottom) < < endl; // } // // void left() { // // Cout < < Java, C + +, Python, Php,... (public classification list) < < endl; // } // // void contert() { // // Cout < < C + + subject video... "<< endl; // } // //}; // //void text() { // // Java ja; // ja.header(); // ja.left(); // ja.contert(); // ja.footer(); // // cout << "------------------------------------------" << endl; // // Python py; // py.header(); // py.left(); // py.contert(); // py.footer(); // // cout << "------------------------------------------" << endl; // // Cpp cpp; // cpp.header(); // cpp.left(); // cpp.contert(); // cpp.footer(); // // //} //Using inheritance implementation class BasePage { public: void header() { cout << "Home page, open class, login, registration...(Public head)" << endl; } void footer() { cout << "Help center, communication and cooperation, station map...(Common bottom)" << endl; } void left() { cout << "Java,C++,Python,Php,...(Public classification list)" << endl; } }; class Java :public BasePage { public: void content() { cout << "Java Subject video..." << endl; } }; class Python :public BasePage { public: void content() { cout << "Python Subject video..." << endl; } }; class Cpp :public BasePage { public: void content() { cout << "C++Subject video..." << endl; } }; void text01() { Java ja; ja.header(); ja.left(); ja.content(); ja.footer(); cout << "------------------------------------------" << endl; Python py; py.header(); py.left(); py.content(); py.footer(); cout << "------------------------------------------" << endl; Cpp cpp; cpp.header(); cpp.left(); cpp.content(); cpp.footer(); } int main() { // text(); // Common implementation method text01(); system("pause"); return 0; }
4.6.2 mode of inheritance
Inheritance syntax: class subclass: inheritance method parent class
There are three inheritance methods:
- Public inheritance (public)
- protected inheritance
- Private inheritance ()
Example:
#include <iostream> using namespace std; class Base { public: int mA; protected: int mB; private: int mC; }; class Sun1 :public Base { public: void cs() { mA = 100; mB = 100; //mC = 100; // Cannot access because MC is private } }; void text01() { Sun1 s1; s1.mA = 100; //s1.mB = 100; // Cannot access because MB is a protected permission } class Sun2 :protected Base { public: void cs() { mA = 100; mB = 100; //mC = 100;// Cannot access because MC is private } }; void text02() { Sun2 s2; //s2.mA = 100; // Unable to access, because Ma inheritance uses protected inheritance, Ma has also been changed to protected permission during inheritance } class Sun3 :private Base { public: void cs() { mA = 100; mB = 100; //mC = 100;// Cannot access because MC is private } }; void text03() { Sun3 s3; //s3.mA = 100; // Unable to access, because Ma inheritance uses private inheritance, Ma is also changed to private permission during inheritance } int main() { //public inheritance method //text01(); //protected inheritance method //text02(); //priavte inheritance method text03(); system("pause"); return 0; }
4.6.3 object model in inheritance
**Question: * * which members inherited from the parent class belong to the child class objects?
Example:
#include <iostream> using namespace std; class Base { public: int mA; protected: int mB; private: int mC; }; class Sun :public Base { int mD; }; void text() { //All non static member properties in the parent class are inherited into the child class //The private attributes in the parent class are hidden by the compiler, so they cannot be accessed, but they are indeed inherited cout << "Sun size:" << sizeof(Sun) << endl; } int main() { text(); system("pause"); return 0; }
Use the command prompt provided with VS to view the object model cl /d1 reportSingleClassLayout object name and file name cpp
4.6.4 construction and Deconstruction in inheritance
After the subclass inherits from the parent class, the constructor and destructor of the parent class will also be called when the class object is created
Example:
#include <iostream> using namespace std; class Base { public: Base() { cout << "Base Constructor" << endl; } ~Base() { cout << "Base Destructor" << endl; } }; class Sun : public Base { public: Sun() { cout << "Sun Constructor" << endl; } ~Sun() { cout << "Sun Destructor" << endl; } }; void text() { Sun s; } int main() { text(); system("pause"); return 0; }
Summary: in inheritance, the constructor of the parent class is called first, and the constructor of the child class is called in the opposite order
4.6.5 handling method of members with the same name in inheritance
- You can access the member with the same name in the subclass directly
- To access a member with the same name as the parent class, you need to add a scope
Example:
#include <iostream> using namespace std; class Base { public: int ma = 100; void find() { cout << "Base find()" << endl; } void find(int a) { cout << "Base find(int a)" << endl; } }; class Sun : public Base { public: int ma = 200; void find() { cout << "Sun find()" << endl; } }; void text() { Sun s; cout << s.ma << endl; cout << s.Base::ma << endl; s.find(); s.Base::find(); s.Base::find(100); } int main() { text(); system("pause"); return 0; }
Summary:
- Subclass objects can directly access members with the same name in subclasses
- The subclass object plus scope can access the member with the same name as the parent class
- When a subclass has a member function with the same name as the parent class, the subclass will hide the member function with the same name in the parent class, and the scope can access the function with the same name in the parent class
4.6.6 processing method of inheriting static members with the same name
Static members and non static members have the same name and are handled in the same way
- Members with the same name of the subclass can be accessed directly
- Scope is required to access the member with the same name as the parent class
Example:
#include <iostream> using namespace std; class Base { public: static int ma; static void func() { cout << "Base func()" << endl; } }; int Base::ma = 100; class Sun : public Base { public: static int ma; static void func() { cout << "Sun func()" << endl; } }; int Sun::ma = 200; void text01() { Sun s; cout << "Access via object:" << endl; cout << s.ma << endl; cout << s.Base::ma << endl; cout << "Access by class name:" << endl; cout << Sun::ma << endl; cout << Sun::Base::ma << endl; } void text02() { Sun s; cout << "Access via object:" << endl; s.func(); s.Base::func(); cout << "Access by class name:" << endl; Sun::func(); Sun::Base::func(); } int main() { //Static member text01(); //Static function text02(); system("pause"); return 0; }
Summary: static members with the same name are handled in the same way as non static members, except that they can be accessed in two ways (through object and class names)
4.6.7 multi inheritance syntax
C + + allows a class to inherit multiple classes at the same time
Syntax: class subclass: inheritance method parent class name 1, inheritance method parent class name 2, Inheritance method: parent class name n{};
Note: multiple inheritance may cause members with the same name to appear in the parent class, and the scope needs to be added. Therefore, C + + generally does not advocate the use of multiple inheritance syntax
#include <iostream> using namespace std; class Base1 { public: int ma = 100; }; class Base2 { public: int ma = 200; }; class Sun :public Base1, public Base2 { public: int mc = 300; }; void text(){ Sun s; cout << s.Base1::ma << endl; cout << s.Base2::ma << endl; cout << s.mc << endl; //The same is true for accessing member functions } int main() { text(); system("pause"); return 0; }
4.6.8 diamond inheritance
**Diamond inheritance concept: * * two subclasses inherit one parent class at the same time, and the other subclass inherits two subclasses at the same time. This inheritance is called diamond inheritance, or diamond inheritance
Example:
#include <iostream> using namespace std; class Base { public: int mage; }; class Sun1 : virtual public Base { }; class Sun2 : virtual public Base { }; class Grandson : public Sun1, public Sun2 { }; void text() { Grandson g; g.Sun1::mage = 100; g.Sun2::mage = 200; cout << g.Sun1::mage << endl; cout << g.Sun2::mage << endl; } int main() { text(); system("pause"); return 0; }
Summary:
- The main problem caused by diamond inheritance is that subclasses inherit two copies of the same data, resulting in waste of resources and meaninglessness
- Using virtual inheritance can solve the problem of diamond inheritance
**Virtual inheritance key: * * virtual
Syntax: class subclass Name: virtual inheritance method parent class name
4.7 polymorphism
4.7.1 basic concept of polymorphism
Polymorphism is one of the three characteristics of C + + object-oriented
Polymorphisms fall into two categories:
- Static polymorphism: function overloading and operator overloading belong to static polymorphism and reuse function names
- Dynamic polymorphism: the implementation and operation of derived classes and virtual functions are polymorphic
Difference between static polymorphism and dynamic polymorphism:
- Statically polymorphic function address early binding - the function address is determined in the compilation stage
- Dynamic polymorphic function address late binding - function address determined at run time
Dynamic polymorphism meets the following conditions:
- There is an inheritance relationship
- Subclasses override the virtual functions of the parent class
Service conditions of dynamic polymorphism:
The pointer or reference of the parent class points to the child class object
**Virtual inheritance key: * * virtual
Syntax: class subclass Name: virtual inheritance method parent class name
Example:
#include <iostream> using namespace std; class Animal { public: virtual void speak() { cout << "Animals are barking" << endl; } }; class Cat : public Animal { public: void speak() { cout << "The cat is barking" << endl; } }; class Dog : public Animal { public: void speak() { cout << "The dog is barking" << endl; } }; void DoSpeak(Animal& animal) { //Dynamic binding (late binding) is realized by adding virtual before the parent class member function animal.speak(); } void text() { Cat c; DoSpeak(c); Dog d; DoSpeak(d); } int main() { text(); system("pause"); return 0; }
4.7.2 polymorphic case 1: Calculator
#include <iostream> using namespace std; //Common way class JiSuanQi { public: int m_num1; int m_num2; int Add() { return m_num1 + m_num2; } int Sub() { return m_num1 - m_num2; } JiSuanQi(int a = 0, int b = 0) { m_num1 = a; m_num2 = b; } }; void test01() { JiSuanQi j; cout << j.Add() << endl; cout << j.Sub() << endl; } //Polymorphic calculator class DuoTaiJiSuanQi{ public: int m_num1; int m_num2; virtual int SuanFa() { return 0; } }; class Add :public DuoTaiJiSuanQi { int SuanFa() { return m_num1 + m_num2; } }; class Sub :public DuoTaiJiSuanQi { int SuanFa() { return m_num1 - m_num2; } }; void test02() { DuoTaiJiSuanQi *d = new Add; d->m_num1 = 200; d->m_num2 = 100; cout << d->SuanFa() << endl; delete d; d = new Sub; d->m_num1 = 200; d->m_num2 = 100; cout << d->SuanFa() << endl; delete d; } int main() { //Common method to realize calculator //test01(); test02(); system("pause"); return 0; }
4.7.3 pure virtual functions and abstract classes
In polymorphism, the implementation of virtual functions in the parent class is meaningless, which are mainly called through subclass rewriting
Therefore, virtual functions can be changed to pure virtual functions
Pure virtual function syntax: virtual return type function name (parameter list) = 0;
When there are pure virtual functions in a class, this class is also called an abstract class
Abstract class features:
- Unable to instantiate object
- Subclasses must override pure virtual functions in abstract classes, otherwise they cannot be instantiated
Example:
#include <iostream> using namespace std; class Base { public: virtual void func() = 0; }; class Sun : public Base { public: void func() { cout << "call func function" << endl; }; }; void text01() { Sun a; a.func(); Base* p = new Sun; p->func(); delete p; } int main() { text01(); system("pause"); return 0; }
4.7.4 case 2: making drinks
#include <iostream> using namespace std; class BaseDrik{ virtual void Zhushui() { cout << "Boiling water..." << endl; } virtual void ChongPao() = 0; virtual void DaoRu() { cout << "Pouring into a cup..." << endl; } virtual void JiaFuLiao() = 0; virtual void TiShi() { cout << "Finished!" << endl; } public: void ZhiZuo() { Zhushui(); ChongPao(); DaoRu(); JiaFuLiao(); TiShi(); } }; class KaFei : public BaseDrik { void ChongPao() { cout << "Making coffee..." << endl; } void JiaFuLiao() { cout << "Adding sugar and milk..." << endl; } }; class Cha : public BaseDrik { void ChongPao() { cout << "Making tea..." << endl; } void JiaFuLiao() {} }; void ZhiZuo(BaseDrik *p) { cout << "-----------------------" << endl; p->ZhiZuo(); cout << "-----------------------" << endl; } void text() { KaFei k; ZhiZuo(&k); BaseDrik* c = new Cha; ZhiZuo(c); delete c; } int main() { text(); system("pause"); return 0; }
4.7.5 virtual destruct and pure virtual destruct
When polymorphism is used, if the attribute in the subclass is opened to the heap, the parent class pointer cannot call the destructor code of the subclass when it is released
Solution: change the destructor in the parent class to a fictitious function or pure virtual destructor
Function: solves the problem that the parent class pointer reference cannot be released cleanly when releasing the child class object
Virtual destructor and pure virtual destructor have the following commonalities:
- You can solve the problem of releasing child class pointers from parent class pointers
- All need to have specific function implementation
Difference between virtual destruct and pure virtual destruct:
- If it is a pure virtual destructor, this class belongs to an abstract class and cannot instantiate an object
Virtual destructor syntax: virtual ~ class name () {}
Pure virtual destructor syntax: virtual ~ class name () = 0; Because a specific implementation is required, you need to overload the class name outside the class:: ~ class name () {}
Example:
#include <iostream> using namespace std; class Base { public: Base() { cout << "Base constructor call " << endl; } virtual ~Base() { cout << "Base Destructor call" << endl; } virtual void speak() = 0; }; class Sun : public Base { public: int* m_age; Sun(int age) { cout << "Sun constructor call " << endl; m_age = new int(age); } ~Sun() { cout << "Sun Destructor call" << endl; if (m_age != NULL) { delete m_age; m_age = NULL; } } virtual void speak() { cout << "Age:" << endl; } }; void text() { Base* b = new Sun(18); b->speak(); //When the parent class pointer is destructed, it will not call the destructor in the subclass, resulting in memory leakage if there is heap data in the subclass delete b; } int main() { text(); system("pause"); return 0; }
4.7.6 case 3: computer assembly
#include <iostream> using namespace std; class CPU { public: virtual void YunZuo() = 0; }; class XianKa { public: virtual void YunZuo() = 0; }; class NeiCun { public: virtual void YunZuo() = 0; }; class Intel_CPU :public CPU { virtual void YunZuo() { cout << "Intel_CPU" << endl; } }; class AMD_CPU :public CPU { virtual void YunZuo() { cout << "AMD_CPU" << endl; } }; class QiCaiHong_XianKa :public XianKa { virtual void YunZuo() { cout << "Colorful fish display card" << endl; } }; class JiJia_XianKa :public XianKa { virtual void YunZuo() { cout << "Gigabyte graphics card" << endl; } }; class JinShiDun_NeiCun :public NeiCun { virtual void YunZuo() { cout << "Kingston memory" << endl; } }; class Computer { private: CPU* m_cpu; XianKa* m_xianka; NeiCun* m_neicun; public: Computer(CPU *cpu,XianKa *xianka,NeiCun *neicun) { m_cpu = cpu; m_xianka = xianka; m_neicun = neicun; } void GongZuo() { m_cpu->YunZuo(); m_xianka->YunZuo(); m_neicun->YunZuo(); } }; void text() { Computer c1(new Intel_CPU,new QiCaiHong_XianKa,new JinShiDun_NeiCun); c1.GongZuo(); cout << "----------------------------------" << endl; Computer c2(new Intel_CPU, new JiJia_XianKa, new JinShiDun_NeiCun); c2.GongZuo(); cout << "----------------------------------" << endl; Computer c3(new AMD_CPU, new JiJia_XianKa, new JinShiDun_NeiCun); c3.GongZuo(); cout << "----------------------------------" << endl; Computer c4(new AMD_CPU, new QiCaiHong_XianKa, new JinShiDun_NeiCun); c4.GongZuo(); } int main() { text(); system("pause"); return 0; }
5. File operation
The data generated when the program runs belongs to temporary data. Once the program runs, it will be released
Data can be persisted through files
File operations in C + + need to include the file < fstream >
There are two types of files:
- Text files - files are stored in the computer as ASCII text
- Binary files - files are stored in the computer in binary form of text, and users generally can't read them directly
Three categories of operation documents:
- ofstream: write operation
- ifstream: read operation
- fstream: read / write operation
5.1 text documents
5.1.1 writing documents
The steps for writing files are as follows:
1. Include header file
#include <fstream>
2. Create a flow object
ofstream stream name/ fstream stream name
3. Open the file
Stream name open("file path", opening method);
4. Write data
Stream name < < "write data";
5. Close the file
Stream name close();
File opening method:
Open mode | explain |
---|---|
ios::in | Open file for reading |
ios::out | Open file for writing |
ios::ate | Initial location: end of file |
ios::app | Write file in append mode |
ios::trunc | If the file exists, delete it first before creating it |
ios::binary | Open file in binary mode |
**Note: * * the file opening method can be used in conjunction with the | operator
For example, write the file ios::binary | ios::out in binary mode
Example:
#include <iostream> using namespace std; #include <fstream> void text() { fstream f; f.open("f:\\text.txt", ios::app); f << "Name: Zhang San" << endl; f << "Gender: Male" << endl; f << "Age: 18" << endl; f.close(); } int main() { text(); system("pause"); return 0; }
5.1.2 document reading
Reading a file is similar to writing a file, but there are many ways to read it
The steps of reading files are as follows:
1. Include header file
#include <fstream>
2. Create flow object
ifstream stream name/ fstream stream name
3. Open the file and judge whether the file is opened successfully
Stream name open("file path", opening method);
4. Read data
Four ways to read
5. Close the file
Stream name close();
Example:
#include <iostream> using namespace std; #include <fstream> #include <string> void text() { ifstream fp; fp.open("f:\\text.txt",ios::in); if (!fp.is_open()) { cout << "File opening failed!" << endl; return; } First kind //char buf[1024] = { 0 }; //while (fp >> buf) { // cout << buf << endl; //} Second //char buf[1024] = { 0 }; //while (fp.getline(buf, sizeof(buf))) { // cout << buf << endl; //} Third //string buf; //while (getline(fp, buf)) { // cout << buf << endl; //} //Fourth char buf[1024] = { 0 }; for (int i = 0; (buf[i] = fp.get()) != EOF; i++); cout << buf << endl; fp.close(); } int main() { text(); system("pause"); return 0; }
Summary:
- I fstream or fsstream class can be used to read files
- Using IO_ The open function can judge whether the file is opened successfully
5.2 binary files
Read and write files in binary mode
The opening method should be specified as ios::binary
5.2.1 writing documents
Writing files in binary mode mainly uses the stream object to call the member function write
Function prototype: ostream & wirte (const char * buffer, int len);
Parameter interpretation: the character pointer buffer points to a storage space in memory. len is the number of reading and writing sessions
The steps for writing binary files are as follows:
1. Include header file
#include <fstream>
2. Create a flow object
ofstream stream name/ fstream stream name
3. Open the file
Stream name open("file path", opening method);
4. Write data
Stream name write((const char *) write data address, sizeof (write data type));
5. Close the file
Stream name close();
Example:
#include <iostream> using namespace std; #include <fstream> #include <string> class Preson { string m_name; int m_age; public: Preson(string name = "",int age = 0) { m_name = name; m_age = age; } }; void text() { ofstream fp; fp.open("f:\\preson.txt", ios::binary | ios::out); Preson p("Tom",18); fp.write((const char*)&p,sizeof(Preson)); fp.close(); } int main() { text(); system("pause"); return 0; }
new JiJia_XianKa, new JinShiDun_NeiCun);
c3.GongZuo();
cout << "----------------------------------" << endl;
Computer c4(new AMD_CPU, new QiCaiHong_XianKa, new JinShiDun_NeiCun);
c4.GongZuo();
}
int main() {
text(); system("pause"); return 0;
}
## 5. File operation The data generated when the program runs belongs to temporary data. Once the program runs, it will be released Data can be persisted through files C++The file needs to be included in the file operation`<fstream>` There are two types of files: 1. text file - The file is in text ASCII The code form is stored in the computer 2. Binary file - Files are stored in the computer in binary form of text, and users generally can't read them directly Three categories of operation documents: 1. ofstream: Write operation 2. ifstream: Read operation 3. fstream: Read / write operation ### 5.1 text documents #### 5.1.1 writing documents The steps for writing files are as follows: 1.Include header file `#include <fstream>` 2.Create flow object `ofstream Stream name;`/`fstream Stream name` 3.Open file `Stream name.open("File path",Open mode);` 4.Write data `Stream name << "Write data" ;` 5.Close file `Stream name.close();` File opening method: | Open mode | explain | | ----------- | :------------------------- | | ios::in | Open file for reading | | ios::out | Open file for writing | | ios::ate | Initial location: end of file | | ios::app | Write file in append mode | | ios::trunc | If the file exists, delete it first before creating it | | ios::binary | Open file in binary mode | **be careful:**The file opening method can be used together to make use of`|`Operator For example: write files in binary mode`ios::binary | ios::out` **Example:** ```c++ #include <iostream> using namespace std; #include <fstream> void text() { fstream f; f.open("f:\\text.txt", ios::app); f << "Name: Zhang San" << endl; f << "Gender: Male" << endl; f << "Age: 18" << endl; f.close(); } int main() { text(); system("pause"); return 0; }
5.1.2 document reading
Reading a file is similar to writing a file, but there are many ways to read it
The steps of reading files are as follows:
1. Include header file
#include <fstream>
2. Create a flow object
ifstream stream name/ fstream stream name
3. Open the file and judge whether the file is opened successfully
Stream name open("file path", opening method);
4. Read data
Four ways to read
5. Close the file
Stream name close();
Example:
#include <iostream> using namespace std; #include <fstream> #include <string> void text() { ifstream fp; fp.open("f:\\text.txt",ios::in); if (!fp.is_open()) { cout << "File opening failed!" << endl; return; } First kind //char buf[1024] = { 0 }; //while (fp >> buf) { // cout << buf << endl; //} Second //char buf[1024] = { 0 }; //while (fp.getline(buf, sizeof(buf))) { // cout << buf << endl; //} Third //string buf; //while (getline(fp, buf)) { // cout << buf << endl; //} //Fourth char buf[1024] = { 0 }; for (int i = 0; (buf[i] = fp.get()) != EOF; i++); cout << buf << endl; fp.close(); } int main() { text(); system("pause"); return 0; }
Summary:
- I fstream or fsstream class can be used to read files
- Using IO_ The open function can judge whether the file is opened successfully
5.2 binary files
Read and write files in binary mode
The opening method should be specified as ios::binary
5.2.1 writing documents
Writing files in binary mode mainly uses the stream object to call the member function write
Function prototype: ostream & wirte (const char * buffer, int len);
Parameter explanation: the character pointer buffer points to a storage space in memory. len is the number of reading and writing sessions
The steps for writing binary files are as follows:
1. Include header file
#include <fstream>
2. Create flow object
ofstream stream name/ fstream stream name
3. Open the file
Stream name open("file path", opening method);
4. Write data
Stream name write((const char *) write data address, sizeof (write data type));
5. Close the file
Stream name close();
Example:
#include <iostream> using namespace std; #include <fstream> #include <string> class Preson { string m_name; int m_age; public: Preson(string name = "",int age = 0) { m_name = name; m_age = age; } }; void text() { ofstream fp; fp.open("f:\\preson.txt", ios::binary | ios::out); Preson p("Tom",18); fp.write((const char*)&p,sizeof(Preson)); fp.close(); } int main() { text(); system("pause"); return 0; }
Note: This article is not yet completed, and will be updated later