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 |