Constructor and Destructor in C++

1. Introduction

In C++, a constructor is a special member function used to initialize objects of a class. 构造函数的名称与类的名称相同,没有返回值类型,也不需要使用void关键字。构造函数可以有参数和重载, so different objects can be created based on different parameter lists.
The constructor is automatically called when the object is created, and is used to complete the initialization of the object, such as assigning initial values ​​​​to member variables, allocating memory, and so on. You can use the member initialization list in the constructor to assign initial values ​​to member variables, and you can also perform assignment operations in the constructor body.

Second, the constructor

C ++ uses the constructor to realize the assignment of the memory occupied by the object. The constructor is enforced when the object is initialized. If we do not implement the constructor ourselves, the compiler will provide a default constructor. The constructor
is a special member function, which is mainly used to allocate space for the object and initialize it. The name of the constructor must be the same as the class name, and cannot be arbitrarily named by the user. It can have parameters of any type, but cannot have a return value. It does not need to be called by the user, but is automatically executed by the compiler when the object is created. When we use new, we will first call malloc to apply for a heap space, and then call the constructor to assign a value to the requested space.

2.1 Classification of constructors

Constructors have the following special types:

  • Default constructor: A constructor without parameters. If no constructor is defined, the compiler will automatically generate a default constructor.
  • Copy constructor: used to copy an existing object to a newly created object, and the parameter is a reference or a constant reference of the same type.
  • Move constructor: used to transfer the resources of an object referenced by an rvalue to a newly created object, and the parameter is an rvalue reference of the same type.
  • Destructor: It is used to release the resources occupied by the object. It has no parameters and return value types. The name is the class name plus "~".

Definition and usage example of the constructor:

class MyClass{
public:
    //默认构造函数
    MyClass(){
        num = 0;
        str = "default";
    }
    //有参数的构造函数
    MyClass(int n, string s){
        num = n;
        str = s;
    }
    //拷贝构造函数
    MyClass(const MyClass& other){
        num = other.num;
        str = other.str;
    }
    //移动构造函数
    MyClass(MyClass&& other){
        num = other.num;
        str = std::move(other.str);
        //转移右值引用的资源
        other.num = 0;
        other.str.clear();
    }
    //析构函数
    ~MyClass(){
        //释放资源
    }
private:
    int num;
    string str;
};
int main() {
    MyClass obj1; // 调用默认构造函数
    MyClass obj2(10, "Hello"); // 调用有参数的构造函数
    MyClass obj3 = obj1; // 调用拷贝构造函数
    MyClass obj4 = std::move(obj2); // 调用移动构造函数
    return 0;
}

2.2 Constructor Syntax

  • The name of the constructor must be the same as the class name, otherwise the compiler will treat it as a general member function;
  • The constructor has no return value, and its type cannot be specified when defining the constructor;
  • Like ordinary member functions, the function body of the constructor can be written inside the class or outside the class;
  • The constructor is generally declared as a public member, but it does not need and cannot be called explicitly like other member functions, it is automatically called when the object is defined, and it is only executed once;
  • Constructors can take no parameters.
#include<iostream>
using namespace std;
#include<string>
#include<vector>
/*
private 私有的:只有当前类内才有权限访问这个成员(类内)
protected 受保护的:类内和子类有权限访问这个成员(类内子类)
public 公共的:所有位置都有权限访问这个成员(对象,子类,类内)
*/

class people {
private:      //私有的     不可以被对象访问
	int age;
protected:    //受保护的    内类和子类能访问
	bool Gender;
public:       //共有的类内 子类 对象都可以访问
	string name;
	//构造函数的名字和类名相同,有参数(能重载),没有返回值
	people() {
		cout << "无参构造" << endl;
	}
	people(int A) {
		cout << "调用了参数为int A的构造函数" << endl;
	}
	/*people(int A, bool G, string N) {
		age = A;
		Gender = 0;
		name = N;
		cout << "调用了参数为int A,bool G,string N的构造函数" << endl;
	}*/

	people(int age, bool Genger, string name) {
		this->age = age;//this 是个指针,指向了当前对象,this的主要作用是区分成员变量和参数
	}
};
int main() {
	people p1(12);
	people p2(12, 1, "asd");
	people p3;//调用无参构造 如果是people p() 编译器会认为是函数声明不会创建对象
	cout << -------------------------- << endl;
	//在堆区创建对象C++中使用关键字 new,释放堆区内存使用关键字delete
	people *Q = new people();//调用了无参构造函数在堆区创建了对象
	people* Q1 = new people(1);//调用了参数为int A 的构造函数创建了堆区对象
	//释放堆区内存
	delete Q;
	delete Q1;
	//在堆区创建int类型的数组
	int* int_ps = new int[3];//在堆区申请了12个字符的内存
	cout << int_ps[0] << int_ps[1] << int_ps[2] << endl;
	delete[]int_ps;//释放堆区数组要加[]
	//在堆区创建people类型的数组
	people* peo_ps = new people[3];//在堆区创建了3个people类型的对象
	delete[]peo_ps;
	return 0;
}

While creating the object, use the constructor to assign values ​​to the data members, usually in the following form:

类名 对象名[(实参表)]
Score op1(99, 100);
op1.showScore();
类名 *指针变量名 = new 类名[(实参表)]
Score *p;
p = new Score(99, 100);
p->showScore();
-----------------------
Score *p = new Score(99, 100);
p->showScore();

3. Destructor

In C++, a destructor is a special member function in a class, which is used to release and clean up resources when the object is destroyed (clear the heap memory pointed to by the internal pointer of the object) . The destructor name is the same as the class name, but with a tilde (~) prefixed to the name.
** 析构函数没有返回值,也没有参数,页不能重载。**Therefore,
its declaration form is as follows:

class MyClass{
public:
    //构造函数
    MyClass();
    //析构函数
    ~MyClass();
};

When an object is destroyed, its destructor is automatically called. The destruction of the object can be done by the programmer explicitly calling the delete operator, the delete[] operator, or automatically calling the destructor at the end of the object's lifecycle (the stack object is automatically released, and the heap object needs to manually call delete or delete[] operator call).
Because the main function of the destructor is to release resources and clean up operations, we usually complete some object cleanup operations in the destructor, such as releasing dynamically allocated memory, closing file handles, and releasing network connections .
Here is a simple example showing how to free dynamically allocated memory in the destructor:

#include<iostream>
#include<string>    //C++中,string是类,里面包含了方法和属性
using namespace std;
class MyClass{
    int a;
    int b;
    int* p = NULL;
    int* p1 = NULL;
public:
    MyClass(){}
    MyClass(int a){
        p = new int(a);
        p1 = new int [a];
    }
    ~MyClass(){
        if(p) delete p;
        if(p1) delete[] p1;
        cout << "析构函数" << endl;
    }
};
int main(){
    MyClass p(5);
    MyClass* p1 = new MyClass(6);
    delete p1;
    return 0;
}

Description: In the following cases, when the object life cycle ends, the destructor will be called automatically:

  • When the object is created in the stack area, when the object goes out of scope, its destructor will be called automatically
void someFunction(){
    MyClass obj;    //创建对象
    //对象声明周期结束,离开作用域
}   //obj的析构函数自动被调用
  • When an object is created in the heap area, when the object is released using the delete operator, the object's destructor will be called automatically
void someFuntion(){
    MyClass* pObj = new MyClass(0;    //在堆区创建对象
    //在这里使用对象
    delete pObj;    //释放对象
    //pObj的析构函数自动被调用
}
  • When an object is a member of another object, when the object containing the object is destroyed, the object's destructor will be called automatically
class MyContainer{
public;
    MyContainer(){
        pObj = new MyClass();    //创建一个MyClass对象
    }
    ~Mycontainer(){
        delete pObj;    //释放MyClass对象
    }
private:
    MyClass* pObj;
};

In the above example, when the MyContainer object is destroyed, the destructor of the M and Class objects it contains will also be called automatically.
Code example:

#include<iostream>
#include<string>//C++中 string是类,里面包含了方法 和 属性
#include<vector>
using namespace std;

class A {
public:
    //析构函数
	int* p;    //p属于对象,对象在堆区,p就在堆区
	A(int size) {
		p = new int[size];
	}//堆区没有释放,会造成内存泄漏
	//栈区对象自动释放,堆区对象手动释放,都会自动调用析构函数

    //析构函数
	~A() {
		if (p) {
			delete p;
			p = nullptr;    //将p赋值成空指针
		}
		cout << "析构函数" << endl;
	}
};

int main(){
    //A a(3);           //错误
	A* a = new A(3);    //p指针又指向一个堆区
	//不执行析构函数
	//析构函数是在释放对象时自动调用
	delete a;//释放a指向的堆区对象,从而调用析构函数
	return 0;
}//析构函数是为了释放对象里面的指针 指向堆区内存
----------------------------------------------------------------------------------
//输出“析构函数”

Fourth, the default constructor and destructor

The default constructor and destructor are member functions of every class in C++. If there is no explicit definition, they will be executed according to the default implementation provided by the compiler.

4.1 Function

  • Default constructor (constructor without parameters): When creating a class object, it is used to initialize the member variables of the object. If no constructor is explicitly defined, the compiler will provide a default constructor that takes no parameters and initializes the member variables of the object to default values ​​(for example, numeric types are initialized to 0, pointer types are initialized to nullptr, Boolean type is initialized to false, etc).
  • Default destructor (destructor without parameters): at the end of the life cycle of the object, it is used to release the resources occupied by the object. 如果对象有成员变量是指针类型,那么默认析构函数只会释放这些指针所指向内存,而不会释放指针本身的内存。If no destructor is explicitly defined, the compiler provides a default destructor that takes no parameters and releases the memory space occupied by the object.

Notice:
如果类中有成员变量是指针类型,并且这些指针指向的内存是通过 new 运算符分配的,那么就需要自己编写析构函数来释放这些内存。否则类中可能会出现内存泄露问题。

For example, the following is an example of a simple class that contains a member variable of integer type and a member variable of pointer type:

class MyClass{
public:
    MyClass();    //默认构造函数
    ~MyClass();   //默认析构函数
private:
    int m_num;
    int* m_ptr;
};

In the above example, if the constructor and destructor of Myclass are not explicitly defined, the compiler will provide a default implementation. Default constructors and destructors can be explicitly defined by:

MyClass::MyClass(){
    //默认构造函数的实现
}
MyClass::~MyClass(){
    //默认析构函数的实现
}

illustrate:

  • For a class that does not define a constructor, its public data members can be initialized with an initialization parameter list
class MyClass{
public:
    char name[10];
    int age;
};

MyClass my= {"chen", 23};
cout << my.name << my.age << endl;

Constructors can be overloaded, that is, multiple constructors of different forms can be defined in a class to provide different parameter options for creating objects. When creating an object, the system will choose which constructor to call based on the type and number of parameters passed.

For example: Here is an example of a class that defines two constructors:

class MyClass{
public:
    MyClass(){
        //无参构造函数
    }
    MyClass(int value){
        //带有一个int类型参数的构造函数
        m_value = value;
    }
private:
    int m_value;
};

Guess you like

Origin blog.csdn.net/m0_62573214/article/details/131878049