Initialize and clean the data members of objects by learning to construct destructors
1, Constructor
1. Knowledge points
Constructor is a special function, which is mainly used to initialize objects when creating objects, that is, to assign initial values to the member variables of objects
2. Definition of constructor
1. The constructor name is the same as the class name
2. Constructor has no return value type and return value
3. Constructors can be overloaded, and the conditions for function overloading must be met
class student { public: student(){}//Parameterless (default) construction student(int a){}//Parametric structure }
3. Call opportunity
1. When a new object is created, the system will actively call this constructor to initialize the data members in the object
//Call parameterless construction student stu; student* p=new student; //Call construction with parameters student stu(10);//Use stack memory student* p=new student(10);//Use heap memory #include <stdio.h> #include<iostream> using namespace std; class Person { int age; char name[20]; float hight; public: Person()//Custom parameterless construction { age = 18; strcpy(name, "yunfei"); hight = 1.78f; } Person(int x, float y,const char* s)//Belt parameter structure { age = x; hight = y; strcpy(name, s); } void showPerson() { cout << age << "\t" << name << "\t" << hight << endl; } }; int main() { Person* p1 = new Person;//Call parameterless construction p1->showPerson(); delete p1; p1 = new Person(18, 1.80f, "yunfei");//Call construction with parameters p1->showPerson(); delete p1; Person stu;//Instantiate Object - Implicitly Invoke Parameterless Construction stu.showPerson(); //Parameters are passed in the order of parameter definition of the constructor with parameters Person p(18, 1.80, "feiyun"); p.showPerson(); getchar(); return 0; }
4. Features of constructor
1. If a constructor is not shown in a class, the system will automatically give a default (implicit) constructor that does nothing
2. If there are multiple constructors in a class, there will usually be different parameter lists and function bodies
3. If the user provides a parameterless (parameterless) structure, the system will not provide a default structure, and will generally write another parameterless structure by itself
4. If there is only parameter construction but no parameter free construction in the class, you cannot call the default construction method to initialize the object. If you want to initialize the object in this way, you can provide a parameter free construction
5. If the constructor is not under the public attribute, it will result in no access outside the class, so you can no longer define objects outside the class (because you can't initialize an object after you define it)
6. There must be a constructor in the class. The constructor will be called only when the object is created
#include<iostream> #include <stdio.h> using namespace std; class A { int a; int b; public: A() { cout << "A structure" << endl; } void showA() { cout << "Tectonic deconstruction" << endl; } }; //If two objects need to interact with each other, they are managed by a manager instead of passing the objects directly //Relationship between classes - inclusion (friend inheritance) //If a class needs to include an object of another class, it does not directly include the object, but contains a pointer to a class member (only four bytes, small memory) class B { A *a; //new the object in the constructor, and then release it in the destructor, or write a function to release public: B() { cout << "B structure" << endl; } }; int main() { A* p = new A; //(*p).showA(); p->showA(); delete p; getchar(); getchar(); return 0; }
If a class needs to include an object of another class, it does not directly include the object, but contains a pointer to a class member (only four bytes, small memory)
5. Copy Construction
(A special constructor)
1. Copy construction is a special constructor, which uses its own type to construct itself
Function: When defining a new object, use an object of its own type to initialize the new object, copy the value of the member variable, and use the function that everyone has
//Example class student { }; student stu1; student stu1=stu2;//The copy constructor provided by the system will be called here (shallow copy)
Definition of copy structure:
1. If you do not write a copy structure, the system will provide an implicit copy structure. The operation of this copy structure can be understood as assigning data members that already exist in the object to the newly created object one by one with the "=" sign (but when there are pointers, pointers cannot be assigned to each other with the "=" sign, so you should write a copy constructor yourself) (deep copy)
2. Customized copy structure:
Class name (const class name&reference name) {}
1. The const here can be used without adding, but only the original object is used to assign values to the new object, and the original object will not be changed. Therefore, the const is used to prevent the original object from being modified.
2. Using&reference will not call copy construction when passing parameters
//Example class student { int id; public: student(const student&stu)//quote { this->id=stu.id; //Assign the id of the passed object to the id of the current calling object } }
Call of copy structure:
1. When initializing another object with an object of the same type, pay attention to the initialization when defining the object, not the assignment
student stu1; student stu2=stu1;//Implicit call copy construction student stu3(stu2);//Explicitly calling copy construction is equivalent to initializing the same data in stu3 with the data in stu2 student *pstu=new student(stu3);
2. When a function transfers parameters, the formal parameters of the function are class objects
void fun(student stu){} fun(stu1);// Copy construction is used when function calls pass parameters
3. If the return value type of a function is an object, the copy construction is called when the function call ends and the object is returned
student fun1(student stu) { return stu; } //Here, the copy structure will be called twice when the function is called, the function will pass the parameter once, and the function will return once
6. Copy construction
1. Shallow copy
We do not write shallow copies. The system will also provide a default copy structure. The operation of this copy structure can be understood as "=" assignment, which is called shallow copy.
However, there may be a problem when using pointers. If there is a pointer addr in object h1 that points to a piece of memory, then when calling shallow copy to create other objects (like h2), the addr in h2 and the addr in h1 point to the same memory address. This is very dangerous. If one object frees the memory, the pointer of the other object will become a wild pointer
2. Deep copy
That is, deep copy is required only when the above problem exists, and deep copy is to define a copy constructor and apply memory for new objects to save content, instead of two objects pointing to the same memory
class person { char* name; public: person(const person&p)//copy construction { //Apply memory for the pointer of new object to store content, and assign values to other members one by one //strlen is the size of the obtained string, excluding ' 0' name = new char[strlen(p.name) + 1]; strcpy(name, p.name); //Strings can be copied using strcpy, but not other data types. Use memcpy() } person(const char* n)//Constructor { name = new char[strlen(n) + 1];//+1 is to keep ' 0' strcpy(name, n); cout << name << endl; } ~person() { if (name != NULL) { delete[]name; name = NULL; } cout << "person Deconstruction" << endl; } }; void fun(person p)//Equivalent to p=p1 { } int main() { { person p1("sssss"); person p2=p1;//It calls the self written display copy structure fun(p1); } system("pause"); return 0; }
3. Assignment constructor
human f1,f2; f2=f1;//Call assignment constructor - shallow copy //Implement the assignment constructor yourself - equivalent to overloading=, the assignment operator human& operator=(const human& other) { //Prevent human f1;f1=f1, assign a value to yourself if(this==&other) { return *this; } //If necessary, free the dynamic memory of this object, reallocate the memory, and assign values //Specific implementation ....... return *this; //Why return the reference of the object itself? To facilitate continuous assignment, for example: f1=f2=f3; }
be careful:
1. Every time the function parameter is an object, in order not to create a new object to increase the overhead, it is generally a reference parameter transfer, and in order not to change the actual parameter object passed in the function, it is generally decorated with const to prevent the actual parameter object from being modified
2. When the function returns a class object, it will call copy construction to create a new object without reference, and the formal parameter is const constant member, so const human should be used&
const human& getBetter(const human& man1,const human& man2) { if(man1>man2) { return man1; } else { return man2; } }
3. In the initialization list of object array, copy construction will be called when using object initialization
human f1,f2,f3,f4; human f[4]={f1,f2,f3,f4}; //This also calls the copy constructor
2, Destructor
It is mainly used to release memory. Generally, only after using pointers, can we write destructors to release memory
1. Knowledge points
The destructor, like the constructor, is also a special function. Its main function is to automatically call the destructor when the object ends its life cycle to do some cleaning work. For example, when the object has applied for memory, it needs to release the memory itself. The operation of releasing memory can be written in the destructor. When the object dies, it automatically calls the destructor to release memory, Then you don't have to worry about forgetting to release memory
2. Definition of destructor
1. The function name is the same as the class name, and a~
~student(){}
2. No return value type, return value or parameter
3. If the class does not write its own destructor, the system will automatically provide an implicit destructor that does nothing
3. Call timing of destructor
1. The destructor must be under the public attribute
2. When an object dies, it will actively call its destructor
3. Generally, when a pointer in a class applies for memory, we will define a destructor to release memory (to release heap memory)
4. Features of destructor
1. What the destructor does is to clean up the object
2. A class has only one destructor (cannot be overloaded)
3. The destructor can be called any number of times
#include<iostream> #include <stdio.h> using namespace std; class person { char* name; public: person(const char* n)//Constructor { name = new char[strlen(n) + 1];//+1 is to keep ' 0' strcpy(name, n); cout << name << endl; } void setname(const char* n) { name = new char[strlen(n) + 1];//+1 is to keep ' 0' strcpy(name, n); cout << name << endl; } ~person() { if (name != NULL) { delete[]name; name = NULL; } cout << "person Deconstruction" << endl; } }; int main() { { //person *p1 = new person("sssss");// Because this is a pointer and will not die, the destructor will not call itself person p2("sss");//Define a class object p2.~person();//Call destructor cout << "11111" << endl;//In this way, the destructor is called twice, and p2 is called once when it dies }//p handles the {} scope, and the destructor executes cout << "22222" << endl; getchar(); getchar(); return 0; } Call order class A { public: A() { cout << "A structure" << endl; } ~A() { cout << "A Deconstruction" << endl; } }; class B { A a; public: B() { cout << "B structure" << endl; } ~B() { cout << "B Deconstruction" << endl; } }; int main() { { B b;//Because it is created in the stack area, first in, then out //So structure A, structure B, structure B, structure A }//{} is equivalent to the scope. After the scope is out, b will die, so destruct will be executed /*Output: A structure B structure B Deconstruction A Deconstruction */ getchar(); getchar(); return 0; }
3, this pointer
1. Knowledge points
1.this pointer is automatically generated and hidden by the system. We cannot see the definition, but we can use
2.this pointer is not part of the object itself. Its scope is inside the class. When the ordinary function of a class accesses the ordinary member of the class, this pointer always points to the caller object
2. Use of this pointer
1. It must be used in the class and cannot be used outside the class
2. this ->Member name; Or (* this). member name; Represents a member of the caller
3.return this; Indicates that the first address of the current caller object is returned
4.return *this; Indicates that the current caller object is returned
3. The performance of this pointer in code
//The formal parameter of the function in the class has the same name as the member in the class void myclass::fun(int sum) { this->sum=sum; } //In this way, we can point to sum through this pointer to indicate that the sum pointed by this is the sum of the current object, if sum=sum; Then these two sums are formal parameters
When the formal parameter and the member in the class have the same name, this pointer is used to distinguish. The member pointed to by this pointer is a member of the class
class person { int age;//Members in the age class char* name; public: person(int age, const char* name)//age formal parameter { this->age = age; this->name = new char[strlen(name) + 1]; strcpy(this->name, name); } ~person() { if (this->name != NULL) { delete[]this->name; this->name = NULL; } } };