(9) Yu Xia's view of C language -- C + + external articles

Silent feather summer 2021-09-15 09:32:34

Write it at the front

This series is my word by word code , Including examples and experimental screenshots . I am not a computer major , You may not know enough about the things covered in this tutorial , If there is a mistake , Welcome criticism and correction . If you have good advice , Welcome to feedback . It's not easy to code words , If this article helps you , If you have spare money , You can reward and support my creation . If you want to reprint , Please attach my reprint information to the back of the article , And declare my personal information and my blog address , but I must be informed in advance .

If you look from the middle , Please read... Carefully ( One ) Yu xiakan C Language —— sketch , Easy to learn this tutorial . This is C++ Set pieces , I will re assemble the fragmentary things and introduce , There may be some repetition or overlap with the previous .

️ encapsulation

Define the function inside the structure , Is the packaging .

️ class

Structures with functions , Called a class .

️ Member functions

Functions in structures , It's called a member function .

️ Structural parameters

1️⃣ Pass parameters directly using structure

#include <iostream>
using namespace std;
struct my_struct
{
int a;
int b;
int c;
};
int mplus(my_struct &struct_)
{
return struct_.a + struct_.b + struct_.c;
}
int main()
{
my_struct struct_ = { 1,2,3 };
int res = mplus(struct_);
printf_s("%d", res);
system("pause");
return 0;
}
 my_struct struct_ = { 1,2,3 };
mov dword ptr [struct_],1
mov dword ptr [ebp-10h],2
mov dword ptr [ebp-0Ch],3
int res = mplus(struct_);
sub esp,0Ch
mov eax,esp
mov ecx,dword ptr [struct_]
mov dword ptr [eax],ecx
mov edx,dword ptr [ebp-10h]
mov dword ptr [eax+4],edx
mov ecx,dword ptr [ebp-0Ch]
mov dword ptr [eax+8],ecx
call mplus (0C912C0h)
add esp,0Ch
mov dword ptr [res],eax

2️⃣ Use structure pointers / Reference and reference

#include <iostream>
using namespace std;
struct my_struct
{
int a;
int b;
int c;
};
int mplus(my_struct& struct_)
{
return struct_.a + struct_.b + struct_.c;
}
int main()
{
my_struct struct_ = { 1,2,3 };
int res = mplus(struct_);
printf_s("%d", res);
system("pause");
return 0;
}
 my_struct struct_ = { 1,2,3 };
mov dword ptr [struct_],1
mov dword ptr [ebp-10h],2
mov dword ptr [ebp-0Ch],3
int res = mplus(struct_);
lea eax,[struct_]
push eax
call mplus (01A12C0h)
add esp,4
mov dword ptr [res],eax

So try to use structure pointer to pass parameters

3️⃣ Package use

#include <iostream>
using namespace std;
struct my_struct
{
int a;
int b;
int c;
int mplus()
{
return a + b + c;
}
};
int main()
{
my_struct struct_ = { 1,2,3 };
int res = struct_.mplus();
printf_s("%d", res);
system("pause");
return 0;
}
  • The generated disassembly is the same as 2️⃣
  • The function does not belong to this structure , This is only for convenience , But virtual functions take up more 4 Bytes ( No matter how many ).

️ this The pointer

struct my_struct
{
int a;
int b;
int c;
void init(int a,int b,int c)
{
this -> a = a;
this -> b = b;
this -> c = c;
}
int mplus()
{
return a + b + c;
}
};
 my_struct struct_ ;
struct_.init(1, 2, 3);
push 3
push 2
push 1
lea ecx,[struct_] // Send the address to ecx, namely this The pointer
call my_struct::init (05A12C0h)
int res = struct_.mplus();
lea ecx,[struct_] // Send the address to ecx, namely this The pointer
call my_struct::mplus (05A1320h)
mov dword ptr [res],eax
void init(int a,int b,int c)
{
push ebp
mov ebp,esp
sub esp,0CCh
push ebx
push esi
push edi
push ecx
lea edi,[ebp-0CCh]
mov ecx,33h
mov eax,0CCCCCCCCh
rep stos dword ptr es:[edi]
pop ecx
mov dword ptr [this],ecx //this The pointer
this->a = a;
mov eax,dword ptr [this]
mov ecx,dword ptr [a]
mov dword ptr [eax],ecx
this->b = b;
mov eax,dword ptr [this]
mov ecx,dword ptr [b]
mov dword ptr [eax+4],ecx
this->c = c;
mov eax,dword ptr [this]
mov ecx,dword ptr [c]
mov dword ptr [eax+8],ecx
}
pop edi
pop esi
pop ebx
mov esp,ebp
pop ebp
ret 0Ch
  1. this Pointers are passed in by the compiler by default , Usually used ecx Pass parameters .
  2. All member functions have this The pointer , Whether or not to use .
  3. this The pointer can't do ++ and -- Such as operation , Cannot be reassigned .
  4. this The pointer does not take up the width of the structure .

️ Constructors

  1. With the same name as the class and no return value
  2. Execute when creating objects / Mainly used to initialize
  3. There can be multiple ( It's better to have a parameterless ), Called overloading, other functions can also overload
  4. The compiler does not require that

️ Destructor

  1. There can only be one destructor , Cannot overload
  2. Can't take any parameters
  3. Cannot take return value
  4. It's mainly used for cleaning up
  5. The compiler does not require that

️ Creating objects in the heap

new = malloc + Constructors
delete = free + Destructor

int* p = new int;
delete p;
int* p = new int[3];
delete[] p;

️ quote

int main()
{
int x = 2;
int& ref = x; // Define reference types
ref = 3;
printf("%d",ref); // Output is 3
return 0;
}
  1. The reference must be assigned an initial value , And it can only point to one variable ,“ be faithful to one 's husband unto death ”.
  2. Assign values to references , Is to assign a value to the variable it points to , Instead of modifying the value of the reference itself .
  3. Operate on references , It's doing operations on the variables it points to , Instead of doing an operation on the reference itself .
  4. A reference type is a “ Weakened pointer ”.

️ Frequently quoted

void show(const int& content) // Function cannot be modified inside content Value
{
content = 5; // Compiler check , Compile not pass
printf("%d",content);
}

️ Inheritance and encapsulation of object-oriented programming

class Person
{
int age;
char sex;
public:
Person(int age,char sex)
{
setAge(age);
setSex(sex);
}
void setAge(int age)
{
age < 0 ? age = 0 : this->age = age;
}
void setSex(char sex)
{
this->sex = sex == 'b' || sex == 'g' ? sex : 'b';
}
};
class Teacher:public Person // Attention must be paid to public
{
int grade;
public:
Teacher(int age,char sex,int grade):Person(age,sex)
{
setAge(age);
setSex(sex);
SetGrade(grade);
}
void SetGrade(int grade)
{
this ->grade = grade < 0 ? 0 : grade;
}
};

️ analysis
1️⃣ setAge/setSex/SetGrade Series of functions are designed to make the input data more controllable , Better encapsulation .
2️⃣ Teacher(int age,char sex,int grade):Person(age,sex) If there is no :Person(age,sex), The default call is Person() Construct . If Person There's no such function , The compiler will report an error .

️ Polymorphism in object-oriented programming

class Person
{
int age;
char sex;
public:
Person(int age,char sex)
{
setAge(age);
setSex(sex);
}
void setAge(int age)
{
age < 0 ? age = 0 : this->age = age;
}
void setSex(char sex)
{
this->sex = sex == 'b' || sex == 'g' ? sex : 'b';
}
virtual void show() // The use of virtual functions to achieve polymorphism
{
printf("%d %d ",age,sex);
}
};
class Teacher:public Person
{
int grade;
public:
Teacher(int age,char sex,int grade):Person(age,sex)
{
setAge(age);
setSex(sex);
SetGrade(grade);
}
void SetGrade(int grade)
{
this ->grade = grade < 0 ? 0 : grade;
}
void show() // Rewrite the implementation , Shared interface
{
Person::show();
printf("%d",grade);
}
};
// Call this function , You can print Person or Teacher The data in
void Print(Person& per)
{
per.show();
}

️ Pure virtual function

  1. The purpose of virtual function is to provide a unified interface , Inherited subclass overload , Called in polymorphic form .
  2. If the functions in the base class don't have any implementation significance , Then it can be defined as a pure virtual function :
    virtual Return type Function name ( parameter list ) = 0;
  3. Classes with pure virtual functions are called abstract classes , Cannot create object .
  4. Virtual functions can be used directly , It can also be called in polymorphic form after being overloaded by subclasses , Pure virtual functions must be implemented in subclasses before they can be used .

️ Virtual table

  • Here is the implementation code
#include <iostream>
#include <Windows.h>
using namespace std;
class Person
{
int age;
char sex;
public:
Person(int age, char sex)
{
setAge(age);
setSex(sex);
}
void setAge(int age)
{
age < 0 ? age = 0 : this->age = age;
}
void setSex(char sex)
{
this->sex = sex == 'b' || sex == 'g' ? sex : 'b';
}
virtual void show() // The use of virtual functions to achieve polymorphism
{
printf("%d %d ", age, sex);
}
virtual void whoami()
{
puts("Person");
}
};
class Teacher :public Person
{
int grade;
public:
Teacher(int age, char sex, int grade) :Person(age, sex)
{
setAge(age);
setSex(sex);
SetGrade(grade);
}
void SetGrade(int grade)
{
this->grade = grade < 0 ? 0 : grade;
}
void show() // Rewrite the implementation , Shared interface
{
Person::show();
printf("%d", grade);
}
void whoami()
{
puts("Teacher");
}
};
void Print(Person& per)
{
per.show();
}
void whoami(Person& per)
{
per.whoami();
}
int main()
{
Teacher t(20, 'b', 20);
Print(t);
whoami(t);
system("pause");
return 0;
}
  • Through the lower breakpoint , We found that t Variables differ :

stay t Of Person One more member in the __vfptr, This point Virtual table The pointer to , Let's look at the memory layout .

After inspection , The value inside is the function address , The first is to point to Teacher Inside show Address of function , The second is to point to Teacher Inside whoami The address of , This is the so-called virtual table . See how the compiler uses virtual tables to achieve polymorphism , Look at the disassembly below :

void whoami(Person& per)
{
push ebp
mov ebp,esp
sub esp,0C0h
push ebx
push esi
push edi
lea edi,[ebp-0C0h]
mov ecx,30h
mov eax,0CCCCCCCCh
rep stos dword ptr es:[edi]
per.whoami();
mov eax,dword ptr [per]
mov edx,dword ptr [eax]
mov esi,esp
// obtain per The first member of the address , That is to say __vfptr.
mov ecx,dword ptr [per]
// because whoami In the second position of the virtual table , So we need edx+4 That's its address
mov eax,dword ptr [edx+4]
call eax

️ Templates

  • Example
template<c1ass T>
void Sort(T* arr,int nLength)
{
int i;
int k;
for(i=0;i<nLength-1;i++)
{
for(k=0;k<nLength-1-i;k++)
{
if(arr[k]>arr[k+1])
{
T temp =arr[k];
arr[k]= arr[k+1];
arr[k+1]=temp;
}
}
}
}
  • The essence

The compiler helps us generate functions ,T How many kinds? , The compiler generates just how many of these functions .

️ abstract class

effect : As a standard specification , Facilitate subclass management

  1. Classes with pure virtual functions , Called abstract classes (Abstract Class)
  2. Abstract classes can also contain ordinary functions
  3. Abstract class cannot be instantiated

️ copy constructor

The copy constructor is provided by the compiler , There is no need to write , He will copy the original object data to the target object intact , Call it a shallow copy .

#include <iostream>
#include <Windows.h>
using namespace std;
class Person
{
int age;
char sex;
public:
Person(int age, char sex)
{
setAge(age);
setSex(sex);
}
void setAge(int age)
{
age < 0 ? age = 0 : this->age = age;
}
void setSex(char sex)
{
this->sex = sex == 'b' || sex == 'g' ? sex : 'b';
}
void show()
{
printf("%d %d ", age, sex);
}
};
int main()
{
Person p0(20,'b');
Person p(p0);
p.show();
}
  • If there is a pointer in the class , And the assigned data is the content, not a simple address , Need to rewrite .
class Person
{
int age;
char sex;
public:
Person(int age, char sex)
{
setAge(age);
setSex(sex);
}
};
class Teacher :public Person
{
int grade;
public:
Teacher(int age, char sex, int grade) :Person(age, sex)
{
setAge(age);
setSex(sex);
SetGrade(grade);
}
void SetGrade(int grade)
{
this->grade = grade < 0 ? 0 : grade;
}
/* Here is the copy constructor */
Teacher(const Teacher& t):Person(t)
{
// Except for the parent class, it is all implemented by itself
}
/*Person(t) without , The copy construction of the parent class needs to be implemented by itself */
};

️ Assignment overload

  • Here is an example
CBase& operator=(const CBase& ref)
{
m_nLength = ref.m_nLength;
if(m_pBuFfer != NULL)
delete[] m_pBuffer;
m_pBuffer = new char[m_nLength];
memcpy(m_pBufFer,ref.m_pBuffer,m_nLength);
return *this;
}
CSub& operator= ( const CSub& ref)
{
CBase::operator= (ref);
m_nIndex = ref.m_nIndex;
return *this;
}
  • Why can't copy constructors be written like this ?
    Where can a subclass fully inherit the parent class , Except for constructors and destructors , Therefore, you cannot explicitly call the copy constructor of the parent class in the function body .

️ Friends

Friends destroy C++ Object oriented encapsulation features , It is not recommended to use .

class CObject
{
friend void Print0bject(cobject* pObject);
// Tell compiler Print0bject Function can access my private members
private:
int x;
public:
CObject(){}
CObject(int x)
{
this -> x = x;
}
};
void Printobject(cobject* pObject)
{
printf("%d \n",pObject->x);
}

TestFriend All functions in the class can be accessed directly MyObject Private members of , But it's just one-way .

class MyObject
{
friend class TestFriend;
private:
int x;
public:
My0bject(){}
MyObject(int x)
{
this -> x =x;
}
};
class TestFriend
{
public:
void Fn(My0bject* pObject)
{
printf("%d tn", pObject->x);
}

️ Inner class

Private members between inner and outer classes cannot communicate , If a class is used only inside a module , You can hide the class name .

️ Namespace (namespace)

Using namespaces can solve the problem of naming conflicts

  1. All namespaces that are not explicitly named are in the global namespace
#include <iostream>
using namespace x;
int Test()
{
return 0;
}
int main()
{
::Test(); // If x Namespaces also have Test function , In this way
system("pause");
return 0;
}

static keyword

Globalization of private variables and functions , Declare members that do not belong to this class in the class .

class CBase
{
public:
CBase(int x,int y);
static int GetSum(); // Declare static member functions
private:
int x,y;
static int Sum; // Declare static data members
}
int CBase::Sum = 10; // Define and initialize static data members

️ In object-oriented design static Static data members of :

1️⃣ Static data members are stored in the global data area , And must be initialized
2️⃣ Static data members follow the same rules as normal data members public,protected,private Access rules
3️⃣ Static data members of a class have two forms of access :
Class object name . Static data member name Class type name :: Static data member name
4️⃣ Compared to global variables , Using static data members can Avoid naming conflicts and Realize information hiding
5️⃣ Function definitions that appear outside a class cannot specify keywords static
6️⃣ Static members can access each other , Including static member functions, accessing static data members and accessing static member functions
7️⃣ Non static member functions can access static member functions and static data members at will
8️⃣ Static member functions cannot access non static member functions and non static data members

static Implement single instance mode

class CSingleton
{
public:
static CSingieton* GetInstance()
{
if(m_pInstance == NULL)
m_pInstance = new CSingleton();
return m_pInstance;
}
private:
CSingleton(){}
static CSingleton* m_pinstance; // Define static members
};
CSingleton* CSingleton::m_pInstance = NULL;// Initialize static members
int main(int argc, char* agrv[])
{
CSingleton* p1= CSingleton::GetInstance();
CSingleton* p2= CSingleton::GetInstance();
//p1 and p2 The value of is the same
return 0;
}

️ C++ twitter

  1. Inherit : Inheritance is the replication of data , Reduce the duplication of code
  2. Inheritance is not limited to the parent class , It will take everything inherited by the parent class
  3. If subclass ( Write it down as A) There are and parent classes ( Write it down as B) Same members , Subject to subclasses , If you don't want to use duplicate members of the parent class ( Write it down as C), Through A.B::C quote
  4. struct and class Private members in are not absolutely inaccessible , Just can't directly quote , You need a pointer to get .
  5. class And struct The difference between :
    Compiler default class The members in the are private, and struct The members in the are public. So is inheritance ,class Inheritance note that on the inheritance symbol side public Don't leave out .
  6. The pointer of the parent class can point to the object of the child class
  7. operators overloading ( In class , It's just designed to make it easy to write code )
  8. In process oriented design static:“ private ” Global variable of
Please bring the original link to reprint ,thank
Similar articles

2021-09-15

2021-09-15

2021-09-15

2021-09-15