02-1 构造函数和析构函数
对象的初始化和清理是两个非常重要的安全问题。其中,构造函数用于初始化;析构函数用于清理。
- 一个对象或者变量没有初始状态,对其使用的后果是未知的。
- 使用完一个对象或者变量,没有及时清理也会造成一定的安全问题。
c++中使用构造函数和析构函数来解决这种安全问题。这两个函数会被编译器自动调用,完成对象的初始化和清理工作。
对象的初始化和清理工作是编译器强制要求我们做的事情,所以如果我们不提供构造函数和析构函数的话,编译器会自动提供。
但是,编译器自动提供的构造函数和析构函数是空实现。
- 构造函数:主要用于在创建对象的时候为对象的成员的属性赋值,构造函数由编译器自动调用,无须手动调用。
- 析构函数:只要用于在对象销毁前系统自动调用,执行一些清理的工作。
-
构造函数
- 构造函数是什么:用于初始化。
- 构造函数的语法:
类的名称() {}
- 构造函数没有返回值,但是也不能写
void
。 - 函数的名称与类的名称相同
- 构造函数可以有参数,因此可以发生重载(函数重载:相同的函数名称,不同的执行内容。可参考笔记。)
- 程序在调用对象的时候会自动调用构造,无须手动调用,而且会且仅会调用一次。
- 构造函数没有返回值,但是也不能写
#include
#include using namespace std; class Person { private: string name; int age; int password; public: Person() { cout << "这是构造函数" << endl; } }; void test01() { class Person p1; } int main() { test01(); system("pause"); return 0; } 运行结果:(环境:Windows11(arm/Apple M VM)/Visual Studio 2022/Debug/arm64)
这是构造函数 请按任意键继续. . .
这边,我们的
main
函数调用的是test01
函数。而test01
函数仅仅是创建了一个p1
。构造函数是自动允许的。因为我们写了构造函数,所以会运行一下我们写的命令。如果没有写构造函数,那么编译器会自动生成空实现。空实现就是这样:class Person { private: string name; int age; int password; Persion() { } };
在这个例子里面,
Person()
的代码块中没有任何代码,这就是一个空实现。 -
析构函数
- 析构函数是什么:用于删除对象。
- 构造函数的语法:
~类的名称() {}
- 析构函数没有返回值,但是也不能写
void
。 - 函数的名称与类的名称相同,需要在名称前加上波浪号
~
。 - 析构函数不可以有参数,因此不可以发生重载。
- 程序会在对象销毁前自动调用析构函数,无须手动调用,而且会且仅会调用一次。
- 析构函数没有返回值,但是也不能写
#include
#include using namespace std; class Person { private: string name; int age; int password; public: Person() { cout << "这是构造函数" << endl; } ~Person() { cout << "这是析构函数" << endl; } }; void test01() { class Person p1; } int main() { test01(); system("pause"); return 0; } 运行结果:(环境:Windows11(arm/Apple M VM)/Visual Studio 2022/Debug/arm64)
这是构造函数 这是析构函数 请按任意键继续. . .
为什么会执行析构函数?因为我们这边创建的
p1
是在函数test01
中创建的。而函数内的数据存储在栈区,栈区数据,在函数test01
执行完成后自动释放。
构造和析构都是必须有的实现。如果我们不提供,那么编译器会自动提供一个空实现的构造和析构。
:-)