C + + constructors and destructors

Posted by Pha on Sat, 20 Nov 2021 09:09:05 +0100

1, Constructor

        1. How the constructor looks

                (1) . the function name and class name are the same

                (2) . no return value

class Person
{
public:
	Person(){}//Constructor -- > has no return value
protected:
	string name;
	int age;
};

        Note: if you do not write a constructor, there is a default constructor in any class

        2. Features of default constructor

                (1) . the default construction parameter is parameterless

                (2) When we write our own constructor, the default constructor does not exist

#include<iostream>
#include<string>
using namespace std;
class Person
{
public:
	Person(string mName,int mAge)//Constructor
	{
		name = mName;
		age = mAge;
	}
	void print()
	{
		cout <<name << "\t" << age << endl;
	}
protected:
	string name;
	int age;
};
int main()
{
	Person MM = { "Miss Du", 19 };//You can assign values after defining the constructor yourself
	//Person GG; ---> An error is reported because the default constructor does not exist after the constructor is defined
	MM.print();
	while (1);
	return 0;
}

        3. Use of constructor

                (1) . constructors are used when constructing objects

                (2).delete can delete the default constructor

class test{
public:
	test() = delete;//Delete default constructor
protected:
	string name;
	int age;
};
int main()
{
	//test mm;---> Cannot construct because the default constructor has deleted the object without parameters, and a parameterless constructor is required
	while (1);
	return 0;
}

                (3) If you want to use the default constructor after writing the constructor, you can use default

class Person
{
public:
	Person(string mName,int mAge)
	{
		name = mName;
		age = mAge;
	}
	Person() = default;//The default constructor is still available
	void print()
	{
		cout <<name << "\t" << age << endl;
	}
protected:
	string name;
	int age;
};
int main()
{
    Person MM = { "Miss Du", 19 };//You can assign values after defining the constructor yourself
	Person GG; //You can still call the default constructor
	MM.print();
	GG.print();
    while(1);
    return 0;
}

                (4) . allow the constructor to call another constructor, just write it in the initialization parameter list. (recommended)

class Person
{
public:
	/*Person(string mName,int mAge)
	{
		name = mName;
		age = mAge;
	}*/
	//Equivalent to the above writing
	Person(string mName,int mAge):name(mName),age(mAge)
	{
		cout << "I write the initialization parameter list" << endl;
	}
	Person() = default;//The default constructor is still available
	void print()
	{
		cout <<name << "\t" << age << endl;
	}
protected:
	string name;
	int age;
};

    Note:

          ●    This method can be used even if another constructor is not called, so the constructor recommends to use the writing method of initializing the parameter list     

         ●   Only constructors can write initialization parameter lists. (constructor name (parameter 1, parameter 2,...): member 1 (parameter 1), member 2 (parameter 2),... {}) - -- > parameters in members can also be assigned using global variables

         ●   It can avoid problems caused by the same formal parameter name and data member name     

string baby="baby";
class test{
public:
	test() = delete;
	test(int mAge) :name(baby), age(mAge){}
    //Equivalent to the following
    test(stirng mName,int mAge):name(mName),age(mAge){}
protected:
	string name;
	int age;
};

         4. Purpose of constructor

                (1) . used to construct objects

                (2) . more for initializing member data (see code above)

        5. * thinking questions*         

                (1) . why not write a constructor to construct an object?

                        This is because there is a default parameterless constructor, so you can construct parameterless objects

                (2) What is constructor overloading for?

                         In order to construct objects with different looks

2, Destructor

        1. What does the destructor look like

                (1) . no return value

                (2) . no parameters

                (3) . function name: ~ class name

class test{
public:
	test(string mName, int mAge) :name(mName), age(mAge)
	{
		cout << "I write the initialization parameter list" << endl;
	}
	~test();//Destructor
protected:
	string name;
	int age;
};

        Note:

                ● if the destructor is not written, there will be a default destructor

                 ● the destructor does not need to be called by itself. The destructor will be called before the object dies  

        2. Purpose of destructor (when you need to write destructor manually)  

                (1) When the data member in the class is a pointer and dynamically applies for memory, handwritten destructors are required

                (2) The. Destructor is used to free data members and apply for dynamic memory  

#include<iostream>
#include<string>
#include<cstring>
using namespace std;
class Person
{
public:
	Person(const char*mName,int mAge) :age(mAge)
	{
		name = new char[strlen(mName) + 1];
		strcpy(name, mName);
	}
	void print()
	{
		cout << name << "\t" << age << endl;
	}
	/*~Person()
	{
		cout << "I am the destructor "< < endl;
		delete[] name;
	}*/
	//Equivalent to the following
	~Person();//Declared in class, defined outside class
protected:
	char* name;
	int age;
};
Person::~Person()
{
	cout << "I'm a destructor" << endl;
	delete[] name;
}
int main()
{
	{
		Person MM("Miss Du", 19);
		MM.print();
	}
	cout << "Main function" << endl;
	while (1);
	return 0;
}

3, Copy constructor  

        one   Copy constructor function

                  (1) The copy constructor is also a constructor. It looks the same as the constructor, except that the parameters are fixed

                        ● the only parameter of the copy constructor is the reference to the object

                  (2) . no copy constructor is written, and there is also a default copy constructor

          2 copy constructor function

                         ● initialize another object through one object         

class Person
{
public:
	Person(string mName, int mAge) :name(mName), age(mAge){}
	void print()
	{
		cout << name << "\t" << age << endl;
	}
	//copy construction 
	Person(Person& MM){							//Person mm(MM)
		name = MM.name;							//mm.name=MM.name
		age = MM.age;							//mm.age=MM.age
		cout << "I'm a copy constructor" << endl;
	}
protected:
	string name;
	int age;
};
int main()
{
	Person MM("Miss Du", 19);
	MM.print();
	//Explicit copy
	cout << "Explicit copy" << endl;
	Person mm(MM);        //Create another object from one object
	mm.print();
	//Equivalent to the following -- > implicit call
	/*Person mm = MM;
	mm.print();*/
	while (1);
	return 0;
}

         Note: the discriminator overloads and copies functions

    Person girl;
	girl = MM;
	girl.print();    //This operator overload does not call the copy function, which is equivalent to assignment


    Person mm(MM);
	mm.print();    //This is a copy construct

        3. * thinking questions*

                (1) . when to call a copy construct?

                        ● when another new object is created through one object, copy needs to be called

                (2) When does the const modifier need to be added to the copy structure?

                         ● const must be modified when there is an anonymous object assignment operation

                Note: const is usually added when writing the copy constructor

    //Anonymous object
	Person GG = Person("Mr Yan", 19);
	GG.print();
	//When creating anonymous objects, the copy structure must be decorated with const
    Person temp;
	temp = Person("anonymous", 18);
	temp.print();

                (3) . function parameters

void printData(Person MM) //Person MM = argument 
{
	MM.print();
}
void printData2(Person& MM) //No copy exists
{
	MM.print();
}
int main()
{
    Person MM("Miss Du", 19);
    printData(MM);     //Copy constructor called
	printData2(MM);    //No call
    while(1);
    return 0;
}

4, Deep and shallow copy    

        1. Light copy

                 ● the default copy structure is called shallow copy

        2. Deep copy

                 ●   The new memory operation is performed in the copy constructor, and the copy assignment operation is performed

#include<iostream>
#include<string>
#include<cstring>
using namespace std;
class Person
{
public:
	Person() = default;
	Person(const char* mName, int mAge) :age(mAge)
	{
		name = new char[strlen(mName) + 1];
		strcpy(name, mName);
	}
	Person(const Person& MM)
	{
		//name = object.name;
		name = new char[strlen(MM.name) + 1];//Deep copy required
		strcpy(name , MM.name);
		age = MM.age;
	}
	void print()
	{
		cout << name << "\t" << age << endl;
	}
	~Person()//Write your own destructor
	{
		delete[] name;
	}

protected:
	char* name;
	int age;
};
int main()
{
	Person MM("Miss Du", 19);
	Person girl(MM);
	Person gm = MM;
	girl.print();
	gm.print();
	while (1);
	return 0;
}

5, Construction and deconstruction sequence problems

        (1) Ordinary objects are constructed and destructed in reverse order

        (2).new, delete will directly call the destructor

        (3).static object. The life cycle ends when the program is closed, so it is released last

   * Examples*         

#include<iostream>
#include<string>
#include<cstring>
using namespace std;
class Person
{
public:
	Person(string name = "x") :name(name) {
		cout << name;
	}
	~Person(){
		cout << name;
	}
protected:
	string name;
};
int main()
{
	{
		Person MM1("A");                    //A
		static Person MM2("B");             //B
		Person* MM3 = new Person("C");      //C
		Person MM4[4];                      //XXXX
		delete MM3;                         //C
		MM3 = nullptr;
	}                                       //XXXXA
	while (1);
	return 0;                               //B
}//Final answer: abcxxxxab

6, C + + structure

                 ● when a constructor is added to the C + + structure, it can be viewed as a class, except that the default attribute is public, while the default attribute in the class is private

#include <iostream>
#include <string>
using namespace std;
struct MM 
{
	//Default to public attribute
	//The default property in the class is private
//protected:
	string name;
	int age;
public:
	MM(string name) :name(name) 
	{
		cout << "Constructor" << endl;
	}
	MM(const MM& object) 
	{
		name = object.name;
		age = object.age;	
		cout << "copy construction " << endl;
	}
	~MM() 
	{

	}
};
int main() 
{
	//The method of assignment during creation is also to call the constructor
	//Mm object = {"Lisa", 19}; error because there is no constructor with two parameters
	MM  object = { "lisa" };
	cout << object.name << "\t" << object.age << endl;
	//Once a C + + structure has written a constructor, it must be used in the way of C + + classes
	MM mm(object);
	cout << mm.name << "\t" << mm.age << endl;
	return 0;
}

  7, Title

        ● write a string class by yourself to meet the following functions

//1. Implement the creation method in string
    string str1;
    string str2("ILoveyou");
    string str3(str1);
    string str4 = str2;
//2. By implementing data and c_str function prints a string
     cout << str2.c_ str() << endl;  // Print ILoveyou
     cout << str2.data() << endl;   // Print ILoveyou
//3. Implement the link of append string
    string strOne="one";
    string strTwo="two";
    string strThree=strOne.append(strTwo);
    cout<<strThree.data()<<endl;        //onetwo
//4. String comparison
    cout<<strOne.compare(strOne)<<endl;    //0
//5. Freeing memory by handwriting destructor

                             

                                                                                                      

Topics: C C++