C + + object (too lazy to pass the plate)

C++

Constructor

During the execution of C + + program, the general direction of memory is divided into four areas
Code area: the binary code that stores the function body and is managed by the operating system
Global area: store global variables, static variables and constants (string constants, const modified 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

Data stored in different areas have different life cycles

Before running the program
exe executable machine instructions are generated after the program is compiled. Before the program is executed, it is divided into two areas

Instruction storage area of the CPU: the instruction execution area of the machine.
The code area is shared. The purpose of sharing is to have only one code in memory for frequently executed programs.
The code area is read-only. The reason why it is read-only is to prevent the program from accidentally modifying its instructions.

The global variables and static variables are stored in this area.
The global area also contains a 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 is completed.

After the program runs

Stack area: automatically allocated and released by the compiler. It stores the parameter values and local variables of the function
Note: do not return the address of local variables, which is easy to cause illegal operation.
The data opened up in the stack area is automatically released by the compiler. At this time, you can use the returned local variable for the first time, but after this time, the local variable is garbled, and you will have illegal access when you access it again. This is because the compiler will make a reservation when releasing.

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
In C + +, new is mainly used to open up memory in the heap area, and delete is used to release memory
Note: delete should add a [] bracket when releasing the array

[the external chain picture transfer fails, and the source station may have an anti-theft chain mechanism. It is recommended to save the picture and upload it directly (IMG btepygb-1646655233615) (c + +% 2096a22 / untitled. PNG)]

4.25 light copy and deep copy

[the external chain picture transfer fails, and the source station may have anti-theft chain mechanism. It is recommended to save the picture and upload it directly (IMG maaavenqz-1646655233619) (c + +% 2096a22 / untitled% 201. PNG)]

[the external chain picture transfer fails. The source station may have an anti-theft chain mechanism. It is recommended to save the picture and upload it directly (img-XMWqMm1B-1646655233620)(C++%2096a22/Untitled%202.png)]

Const type & UU the default is light copy

Shallow copy is a byte by byte assignment, so the pointer will point to the same block address. When the destructor is free, it may be released repeatedly

In order to solve this situation, we need to use deep copy.

The space of the address pointed to is also copied.

4.26 initialization list

https://www.notion.so

[the external chain picture transfer fails, and the source station may have an anti-theft chain mechanism. It is recommended to save the picture and upload it directly (img-2gd2PhjV-1646655233622)(C++%2096a22/Untitled%203.png)]

Operation like grammar sugar

[the external chain picture transfer fails. The source station may have an anti-theft chain mechanism. It is recommended to save the picture and upload it directly (IMG lhizhgpv-1646655233623) (c + +% 2096a22 / untitled% 204. PNG)]

4.27 class objects as class members

🤭 First construct the class object of the member, and then call the constructor,

In other words, the constructor will not be called until the member variable is constructed

In the case of deconstruction, first deconstruct the class object, and then mobilize its own destructor.

4.27 static members

Static member function. All objects share one function.

It can be accessed through object and class name

Person p;

p.func();

Person::func;

Static member functions can only access static member variables

Because it can be accessed through the class name, the class has not been initialized

4.30 storage of class (empty object) 🥰)

🤑 The memory space occupied by empty objects is 1, which is to distinguish the memory space occupied by empty objects

Empty object: class Person {}

🥰class Person{int a}

The size is 4

🥰 Jintai member function does not occupy the memory of the object;

😬 Non static member functions are also on objects that do not belong to classes

!!! Only non static member variables belong to the memory of the class

4.31this pointer 😿 (it is essentially a pointer constant and cannot change the direction)

🤒

[the external chain picture transfer fails. The source station may have anti-theft chain mechanism. It is recommended to save the picture and upload it directly (img-8yIuP00X-1646655233625)(C++%2096a22/Untitled%205.png)]

  • The name conflict is solved. The formal parameter of the function has apple and the member variable has apple. This is this apple = apple
  • this→age
  • this points to the object to which the called member function belongs
  • Chain operation
Person & add(Person &p)
{
	this->age += p.age;
	return this;
}
p.add(10).add(10);

If there is no reference, it returns a copy value, that is, it returns a fake of this, which is a new object.

Person add(Person &p)
{
	this->age += p.age;
	return *this;
}
Then the copy is returned

4.32 null pointer can call member functions (static + non static) 😊

[the external chain picture transfer fails. The source station may have an anti-theft chain mechanism. It is recommended to save the picture and upload it directly (img-C9IkmvFb-1646655233626)(C++%2096a22/Untitled%206.png)]

[the external chain picture transfer fails. The source station may have an anti-theft chain mechanism. It is recommended to save the picture and upload it directly (img-NHvd972k-1646655233628)(C++%2096a22/Untitled%207.png)]

The first one does not call non static class member variables, so there is no error

The second will have a nullpointer error

Solution, if(this==null)

4.34 constant functions and constant objects (mutable is used in the variable, and the constant function can also modify the variable of this)

Constant function added to tail

  • When const is added, it is called a constant function
  • You cannot modify the properties of a member within a constant function
  • After the member attribute is declared as the home keyword mutable, it can still be modified in the constant function.

Constant object

  • The declared object Qian family const is called a constant object
  • Constant objects can only call constant functions 🤩

[the external chain picture transfer fails. The source station may have an anti-theft chain mechanism. It is recommended to save the picture and upload it directly (img-9iFy0rBm-1646655233629)(C++%2096a22/Untitled%208.png)]

[the external chain picture transfer fails. The source station may have an anti-theft chain mechanism. It is recommended to save the picture and upload it directly (img-wDLv1lxW-1646655233632)(C++%2096a22/Untitled%209.png)]

[the external chain picture transfer fails, and the source station may have an anti-theft chain mechanism. It is recommended to save the picture and upload it directly (img-7y0T4CYy-1646655233633)(C++%2096a22/Untitled%2010.png)]

In conclusion, as long as mutable is added, both constant functions and constant objects can modify the value of member variables

🤣

4.40 global functions as friends 👨🏾‍✈️

[the external chain picture transfer fails. The source station may have an anti-theft chain mechanism. It is recommended to save the picture and upload it directly (img-97DMq3G8-1646655233635)(C++%2096a22/Untitled%2011.png)]

[the external chain picture transfer fails. The source station may have an anti-theft chain mechanism. It is recommended to save the picture and upload it directly (img-133maj55-1646655233636)(C++%2096a22/Untitled%2012.png)]

If void goodGay (Building* building) is defined outside the class, you can access the private properties in the class

4.41 friends

There is p'ri've

#include <iostream>
#include <string>
using namespace std;

class House{
    friend class Fri;
private:
    string m_bedroom;
public:
    string m_tennd;
    House();
};
//Out of class member variable
House::House(){
    m_bedroom = "bedroom";
    m_tennd = "a living room";
};

class Fri{
public:
    House *house;
    Fri();
    void visitbedroom();
    void visittennd();
};
Fri::Fri(){
    this->house =new House;
}
//Out of class implementation
void Fri::visitbedroom(){
    cout<<house->m_bedroom;
}
void Fri::visittennd(){
    cout<<house->m_tennd;
}
int main(void){
    Fri p;
    p.visitbedroom();
}

4.42 member functions as friends

[the external chain picture transfer fails. The source station may have an anti-theft chain mechanism. It is recommended to save the picture and upload it directly (img-4nlxkMHx-1646655233637)(C++%2096a22/Untitled%2013.png)]

It's no different from the global function. In essence, it's just the scope of GoodGay.

4.50 operator overloading

For built-in data types, the compiler knows how to operate

[the external chain picture transfer fails. The source station may have an anti-theft chain mechanism. It is recommended to save the picture and upload it directly (img-JKssmODh-1646655233638)(C++%2096a22/Untitled%2014.png)]

#include <iostream>
#include <string>
using namespace std;
class Person{
    friend ostream& operator<<(ostream &c,Person &p);
public:
    int m_age;
    string m_name;
    Person(const Person& p){
        this->m_age = p.m_age;
        this->m_name = p.m_name;
        cout<<"Copy constructor start"<<"this->m_age:"<<this->m_age<<this->m_name<<endl;
    }
    Person(int age,string name="chiguozi"){
        this->m_age = age;
        this->m_name = name;
        cout<<"Constructor start"<<"this->m_age:"<<this->m_age<<this->m_name<<endl;
    }
    Person & operator+(Person p){
        this->m_age+=p.m_age;
        return *this;
    }
    void showAge(){
        cout<<"Age is"<<this->m_age<<endl;
    }
    //The front of doubt++
    Person &operator++(){
        this->m_age++;
        return *this;
    }
    //Space occupying symbol
    //Postposition++
    Person &operator++(int){
        Person temp = *this;//Create copy
        this->m_age +=1;
        return temp;
    }
    //System default constructor
    Person &operator=(Person&p){
        cout<<"=No. 1 overload started"<<endl;
        this->m_age = p.m_age;
        this->m_name = p.m_name;
        return *this;
    }
    //functor 
    void operator()(string s){
        cout<<s;
    }

};

//You can only use global functions to overload, because if you use member variables, the target is cout < < p, which will become p.operate < < (& cout)
//Formal parameters are references
ostream& operator<<(ostream &c,Person &p){
    return cout<<"Age is:"<<p.m_age<<"The name is:"<<p.m_name<<endl;
}
int main(void){
    Person p ={10,"c++"};
    Person c(20,"c--");
    Person f = c;
    p=c;
    (p+p+p+p).showAge();
    p.operator++();
    ++p;
    p("123");
    cout<<p<<p<<p;
}

4.62 succession

[the external chain picture transfer fails, and the source station may have an anti-theft chain mechanism. It is recommended to save the picture and upload it directly (IMG wgcoqmic-1646655233640) (c + +% 2096a22 / untitled% 2015. PNG)]

The inheritance method determines the highest permission of the inherited element of the subclass. private is inaccessible to the subclass.

Will be downgraded

4.63 inherited memory (will inherit all father's things)

class father{
public:
	int gg;//4 bytes
private:
	int mm;//4 bytes
}

class Son:private father{
public:
  int ff;
}

sizeof(Son)It should be 4+4+4,although mm yes son Unable to access, but due to son Will record all the things of the parent class. At this time
mm Will be saved in Son in

[the external chain picture transfer fails. The source station may have an anti-theft chain mechanism. It is recommended to save the picture and upload it directly (img-D3gkMP4f-1646655233642)(C++%2096a22/Untitled%2016.png)]

Distribution map in class

4.64 calling order of constructors and destructors in inheritance

Son son;
  • The constructor of the parent class will be called first
  • Then call the constructor of the subclass
  • First use the destructor of the subclass
  • Finally, use the constructor of the parent class

4.65 when the parent and child have data / functions with the same name

#include <iostream>
using namespace std;
class Father{
public:
    int aa;
    Father(){
        //
        cout<<"The parent class constructor is created"<<endl;
        this->aa = 1;
        this->bb = 2;
    }
    ~Father(){
        cout<<"Parent class destructed"<<endl;
    }
private:
    int bb;

};
class Son:public Father{
public:
    int aa;
    Son(){
        //
        cout<<"The subclass constructor is created"<<endl;
        this->aa = 3;
        this->bb = 4;
    }
    ~Son(){
        cout<<"Subclass destructed"<<endl;
    }
private:
    int bb;
};
int main(void){
    Son s;
    cout<<s.aa;
    cout<<s.Father::aa;
    //cout<<s.bb;
}

🥵 Use:: to determine the scope.

About member functions with the same name

🥰 If a member function with the same name as the parent class appears in the subclass, the member with the same name in the subclass will hide all members with the same name in the parent class

class Father{
		void happy(){}
		void happy(int a){}
}
class Son{
		void happy(){}
}

int main(){
		Son s;
		s.happy();//Can run
		s.Father::happy();//Can run
		s.happy(10);//Can't run, because happy has the same name, and everything of the parent class will be hidden
		s.Father::happy(10);//Can run
}

In summary, subclass members are accessed first. Subclass objects with scope can access members with the same name of the parent class. When the parent class and subclass have functions with the same name, all functions with the same name of the parent class will be hidden. At this time, those who do not add scope must be subclass members, and those who want to call the parent class must add scope;

4.66 processing of static members with the same name 🧐)

Processing method and scope can be added

1. Access data through objects

Son s;
s.m_A;
s.Father::m_A;

2. Access data by class name

Son::m_A;
Son::Father::m_A

3. Functions can be accessed by class name or object;

Son::func();
Son::Father::func();

In summary, subclass members are accessed first. Subclass objects with scope can access members with the same name of the parent class. When the parent class and subclass have functions with the same name, all functions with the same name of the parent class will be hidden. At this time, those who do not add scope must be subclass members, and those who want to call the parent class must add scope;

4.67 multiple inheritance syntax (not recommended) (all constructed)

class Son :public Base1,public Base2{

}

In case of multiple inheritance, the parent class objects will be constructed again. In this way, if a son object is constructed, there will be three objects

[the external chain picture transfer fails. The source station may have an anti-theft chain mechanism. It is recommended to save the picture and upload it directly (IMG gysdfaqy-1646655233644) (c + +% 2096a22 / untitled% 2017. PNG)]

When there are members with duplicate names in the parent class, the scope should be distinguished

4.68 diamond inheritance (virtual inheritance should be used)

[the external chain picture transfer fails, and the source station may have an anti-theft chain mechanism. It is recommended to save the picture and upload it directly (img-ZXny1TUX-1646655233646)(C++%2096a22/Untitled%2018.png)]

[the external chain picture transfer fails. The source station may have anti-theft chain mechanism. It is recommended to save the picture and upload it directly (img-DYcbF9PZ-1646655233647)(C++%2096a22/Untitled%2019.png)]

[the external chain picture transfer fails. The source station may have an anti-theft chain mechanism. It is recommended to save the picture and upload it directly (img-Z7oPR5u3-1646655233648)(C++%2096a22/Untitled%2020.png)]

We found that there are two age s, one is the animal inherited by sheep and the other is the animal inherited by tuo

👹 ps if you want to call age, you have to sheeptuo:: sheet age; Distinguish which father's father

At this time, virtual becomes virtual inheritance

The Animal class becomes a virtual base class

class Animal{
public:
		int age;
}
class Sheep:virtual public Animal{}
class Tuo:virtual public Animal{}
class SheepTuo:public Sheep,public Tuo{}

After virtual inheritance occurs, the age of Animal will be shared;

[the external chain picture transfer fails. The source station may have an anti-theft chain mechanism. It is recommended to save the picture and upload it directly (IMG cjsghlqj-1646655233649) (c + +% 2096a22 / untitled% 2021. PNG)]

A virtual table is constructed to share m_Age object

There is also a vbptr virtual base class pointer (virtual bast ptr) pointing to a vbtable virtual base class table

[the external chain picture transfer fails. The source station may have anti-theft chain mechanism. It is recommended to save the picture and upload it directly (img-Bd9rTVv1-1646655233651)(C++%2096a22/Untitled%2022.png)]

There is an offset in the table, which can be offset from the current pointer by n bits to m_age

For example, 0 + 8, 4 + 4, finally to the position of 8, 8 ~ 12 are equipped with m_Age

[the external chain picture transfer fails. The source station may have an anti-theft chain mechanism. It is recommended to save the picture and upload it directly (img-LA1FeuwS-1646655233652)(C++%2096a22/Untitled%2023.png)]

Now instead of inheriting data, you inherit a pointer.

4.71 polymorphism

  • Static polymorphism: function overloading and operator overloading belong to static polymorphism and reuse function names
  • Dynamic polymorphic derived classes and virtual functions implement runtime polymorphic functions plus virturl

difference

Statically polymorphic function addresses are bound early, and the function address is determined in the compilation stage

Dynamic polymorphic function address late binding operation stage determines function address

A parent class reference receives a child class object

The last call is the speak of the parent class!!!

The address is bound early. The function address has been determined in the compilation stage → only the parent class will be used

class Animal{speak..}
class Cat:public Animal{speak}

void AnimalSpeak(Animal &animal){
		animal.speak();
}
int main(void){
		Cat cat;
		AnimalSpeak(cat);
}

If you want the subclass to speak, adding virtual to the parent class is equivalent to rewriting it in java

class Animal{virtual speak..}
class Cat:public Animal{speak}

void AnimalSpeak(Animal &animal){
		animal.speak();
}
int main(void){
		Cat cat;
		AnimalSpeak(cat);
}

🥰 Conditions of dynamic polymorphism

  1. There is an inheritance relationship
  2. The subclass overrides the virtual function of the parent class (overloading means different parameters, the function name is the same, rewriting means the name is the same, the return value is the same, and the formal parameter list is the same)

4.71 polymorphism analysis

class Animal{
	public:
		void speak(){}
}
//sizeof(Animal)=1
class Animal{
	public:
		virtual void speak(){}
}
//sizeof(Animal)=4

Why does it change after adding virtual? The reason is that after adding virtual

There will be one more vfptr. What is this? virtual function ptr points to vftable virtual function table!!!

Before rewriting

[the external chain picture transfer fails. The source station may have anti-theft chain mechanism. It is recommended to save the picture and upload it directly (img-O8F5O6nK-1646655233654)(C++%2096a22/Untitled%2024.png)]

The internal structure of cat class inherits the vfptr of the parent class, and the vftable pointed to by this ptr has a function of & Animal:: speak

After rewriting

[the external chain picture transfer fails, and the source station may have an anti-theft chain mechanism. It is recommended to save the picture and upload it directly (img-Pc2btSOw-1646655233656)(C++%2096a22/Untitled%2025.png)]

[the external chain picture transfer fails, and the source station may have an anti-theft chain mechanism. It is recommended to save the picture and upload it directly (img-9DiMqFq5-1646655233657)(C++%2096a22/Untitled%2026.png)]

The memory structure is Animal. There is a vfptr pointer pointing to Animal::speak;

[the external chain picture transfer fails, and the source station may have an anti-theft chain mechanism. It is recommended to save the picture and upload it directly (IMG azaahflf-1646655233659) (c + +% 2096a22 / untitled% 2027. PNG)]

When rewriting occurs, it will overwrite Animal's speech and become catspeech;

4.72-73 pure virtual function → abstract class

Pure virtual function

virtual return value type function name (parameter list) = 0

virtual void happy(int a)=0;

As long as there is a pure virtual function, this class is called an abstract class

  1. Cannot instantiate object
  2. The subclass of an abstract class must override the pure virtual function in the parent class, otherwise it also belongs to an abstract class, which is equivalent to that the subclass cannot be instantiated, and the pointer can be used if it cannot be instantiated

,

class Father{
		virtual void happy(int a) = 0;
}
class Son{
		void happy(int a);
}
int main(void){
		Father * f = new Son;
}
#include <iostream>
using namespace std;
class AbstractDrink{
public:
    virtual void boilwater()=0;
    virtual void putThings()=0;
    virtual void driking()=0;
    void makeDrink(){
        boilwater();
        putThings();
        driking();
    }
};
class Tea:public AbstractDrink{
    void boilwater(){
        cout<<"Boil water for tea"<<endl;
    }
    void putThings(){
        cout<<"Put tea"<<endl;
    }
    void driking(){
        cout<<"drink tea"<<endl;
    }
};
class Coke:public AbstractDrink{
    void boilwater(){
        cout<<"Boil water for coke"<<endl;
    }
    void putThings(){
        cout<<"Put coke syrup"<<endl;
    }
    void driking(){
        cout<<"Drink coke"<<endl;
    }
};
void makethings(AbstractDrink *t){
    t->makeDrink();
}
int main(void){
    AbstractDrink *t = new Tea;
    AbstractDrink *c = new Coke;
    makethings(t);
    makethings(c);
}

4.74 virtual deconstruction and pure virtual deconstruction

Virtual deconstruction

When using a parent class pointer to point to a child class object

Animal * c = new Cat;
There will be
Animal Constructed
cat Constructed
Animal Destructed

and cat Not destructed

In order to solve the problem that cat is not destructed, the concept of virtual destructor should be introduced at this time

virtual ~Animal(){};

At this time

Animal is constructed
cat is constructed

cat deconstruction
Animal Deconstructed

Pure virtual destructor: it needs to be declared and implemented

virtual ~Animal(){};=0'

At this time, if you don't write down the specific implementation, you can't run at all. Add the implementation of Animal::~Animal() {} to the class

Let's talk about why we can't run?

The specific reason is that some parent classes need to force their children to release memory, and the parent class itself also needs to release heap memory. If it is not implemented, connection errors will occur

Similarities and differences between virtual destruct and pure virtual destruct

generality

You can solve the problem of releasing subclass objects from parent class pointers

If there is no heap data in the subclass, virtual destructors and spring virtual destructors can not be written

All need specific function implementation

difference

If it is a pure virtual destructor, this class belongs to an abstract class and cannot instantiate an object

Keywords: C++

Added by grantf on Mon, 07 Mar 2022 14:27:03 +0200