VS C + + learning notes

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:

  1. Single line comment: / / description
  2. 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:

  1. #Define macro constant: #define constant name constant value
    • It is usually defined above the file to represent a constant
  2. 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:

asmdoifreturntypedef
autodoubleinlineshorttypeid
booldynamic_castintsignedtypename
breakelselongsizeofunion
caseenummntablestaticunsigned
catchexplicitnamespacestatic_castusing
charexportnewstructvirtual
classfalseprivatetemplatevolatile
const_castfloatprotectedthiswchar_t
continueforpublicthrowwhile
defaultfriendregistertrue
deletegotoreinterpret_casttry

1.6 identifier naming rules

Function: when C + + specifies to name identifiers (variables and constants), it has its own set of rules

  1. Identifier cannot be a keyword
  2. The identifier can only be composed of letters, numbers and underscores
  3. 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 typeOccupied spaceValue 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:

  1. Single precision float
  2. Double precision double

The difference between the two is that the range of significant numbers is not used

data typeOccupied spaceSignificant digit range
float4 bytes7 significant digits
double8 bytes15 ~ 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 charactermeaningASCII value (decimal)
\acall the police007
\bBackspace (BS) to move the current position to the previous column008
\fPage feed (FF) moves the current position to the beginning of the next page012
\nLine feed (LF) moves the current position to the beginning of the next line010
\rPress enter (CR) to move the current position to the beginning of the line013
\tHorizontal tabulation (HT) (skip to next TAB position)009
\vVertical tabulation (VT)011
\\Represents a backslash character '\'092
\'Represents a single quotation mark039
\"Represents a double quotation mark034
?Represents a question mark063

2.6 string type

Function: used to represent a string of characters

Two styles

  1. C style string:

    Syntax: char variable name [] = "string value"

  2. 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 typeeffect
Arithmetic operatorUsed to process four operations
Assignment Operators Used to assign the value of an expression to a variable
Comparison operatorUsed to compare expressions and return a true or false value
Logical operatorUsed 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:

operatortermExamplesresult
+Plus sign+55
-Symbol-5-5
+plus10+515
-reduce10-55
*ride10*550
/except10/52
%Mold taking (residual)10%31
++Pre incrementa=2;b=++a;a=3,b=3
++Post incrementa=2;b=a++a=3,b=2
Pre decrementa=2,b=–aa=1,b=1
Post decrementa=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:

operatortermExamplesresult
=assignmenta=5a=5
+=Plus equalsa=5;a+=5a=10
-=Minus equalsa=5;a-=5a=0
*=Multiply equala=5;a*=5a=25
/=Division equalsa=5;a/=5a=1
%=Modulo equalsa=5;a%=2a=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:

operatortermExamplesresult
==be equal to11,121,0
!=Not equal to1!=1,1!=20,1
<less than1<2,2<11,0
<=Less than or equal to1<=1,2<=11,0
>greater than1>2,2>10,1
>=Greater than or equal to1>=2,1>=10,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:

operatortermExamplesresult
!wrong!aIf a is true, the result is false; If a is false, the result is true
||ora||bIf 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
&&Anda&&bOnly 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:

  1. Constant pointer const int * p

    Features: the pointer can be modified, but the value pointed by the pointer cannot be modified

  2. Pointer constant int * const p

    Features: the value pointed by the pointer can be modified, but the pointer cannot be modified

  3. 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:

  1. struct structure name variable name
  2. struct structure name variable name = {member value...}
  3. 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 () {}

  1. Constructor, no return value and no void
  2. The function name is the same as the class name
  3. Constructors can have arguments, so overloading can occur
  4. 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 () {}

  1. Destructor, no return value, no void
  2. The function name is the same as the class name, and the symbol is added before the name~
  3. Destructors cannot have parameters, so overloading cannot occur
  4. 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

  1. Default constructor (no parameters, empty function body)
  2. Default destructor (no parameters, empty function body)
  3. 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

  1. Default constructor (no parameters, empty function body)
  2. Default destructor (no parameters, empty function body)
  3. The default copy constructor copies the values of attributes
  4. 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:

  1. Subclass objects can directly access members with the same name in subclasses
  2. The subclass object plus scope can access the member with the same name as the parent class
  3. 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:

  1. There is an inheritance relationship
  2. 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:

  1. Text files - files are stored in the computer as ASCII text
  2. 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:

  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 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 modeexplain
ios::inOpen file for reading
ios::outOpen file for writing
ios::ateInitial location: end of file
ios::appWrite file in append mode
ios::truncIf the file exists, delete it first before creating it
ios::binaryOpen 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

Keywords: C++

Added by marcth on Thu, 20 Jan 2022 22:39:04 +0200