一、什么是构造函数?

构造函数在对象实例化时被系统自动调用,仅且调用一次。前面我们学过类,实际上定义类时,如果没有定义构造函数和析构函数,编译器就会生成一个构造函数和析构函数,只是这个构造和析构函数什么事情也不做,所以我们不会注意到一点。

构造函数的特点如下:
(1) 构造函数必须与类名同名;
(2) 可以重载,
(3) 没有返回类型,即使是 void 也不行。

二、什么是析构函数?

与构造函数相反,在对象结束其生命周期时系统自动执行析构函数。实际上定义类时,编译器会生成一个析构函数。
析构函数的特点如下:
(1) 析构函数的格式为~类名();
(2) 调用时释放内存(资源);
(3) ~类名()不能加参数;
(4) 没有返回值,即使是 void 也不行。

三、示例

新建一个目录04_structor_example,编辑一个 04_structor_example.cpp 内容如下

1 #include <iostream>
2 #include <string>
3 using namespace std;
4
5 class Dog
6 {
7 public:
8 Dog();
9 ~Dog();
10 };
11
12 int main()
13 {
14 Dog dog;
15 cout<<"构造与析构函数示例"<<endl;
16 return 0;
17 }
18
19 Dog::Dog()
20 {
21 cout<<"构造函数执行!"<<endl;
22 }
23
24 Dog::~Dog()
25 {
26 cout<<"析构函数执行!"<<endl;
27 }


我们还是以简单的狗类作为示例,定义一个狗类,把构造函数和析构函数写上。前面不是说会自动生成构造函数和析构函数的吗?注意是编译时,编译器生成的。当我们要使用构造函数和析构函数时需要我们自己在类里添加。
第 5 至第 10 行,定义了一个狗类,并在里面写了构造函数和析构函数。
第 14 行,使用 Dog 类实例化一个 dog 对象。
第 15 行,打印一句”构造与析构函数示例”。
第 19 至 22 行,类的函数可以在类里实现,也可以在类外实现,不过在类外实现时需要使
用“::”,此时我们把类的构造函数定义在类的外面,打印一句”构造函数执行!“。
第 14 至 27 行,类的析造函数定义在类的外面,打印一句”析造函数执行!”。

然后编译运行

其实执行的结果也是可以预测的,在对象实例化时会调用构造函数,所以 Dog()先执行,然后再在 main()函数里继续执行 cout<<“构造与析构函数示例”<<endl;。最后对象生命周期结束时才会执行析构函数。

四、this指针

一个类中的不同对象在调用自己的成员函数时,其实它们调用的是同一段函数代码,那么成员函数如何知道要访问哪个对象的数据成员呢?
没错,就是通过 this 指针。每个对象都拥有一个 this 指针,this 指针记录对象的内存地址。在 C++中,this 指针是指向类自身数据的指针,简单的来说就是指向当前类的当前实例对象。

关于类的 this 指针有以下特点:
(1) this 只能在成员函数中使用,全局函数、静态函数都不能使用 this。实际上,成员函数默认第一个参数为 T _ const this。也就是一个类里面的成员了函数 int func(int p),func 的原型在编译器看来应该是 int func(T _ const this,int p)。
(2) this 在成员函数的开始前构造,在成员函数的结束后清除。
(3) this 指针会因编译器不同而有不同的放置位置。可能是栈,也可能是寄存器,甚至全局变量。

以简单的例子来说明 this 的用法。我们还是以狗类为例,按上面的 this 解释,this 只能够在成员函数使用,并可以指向自身数据。我们就可以写这样简单的例子来说明 this 的用法。
我们在 Qt 里也会遇到 this 这个东西,下面这个例子就很容易解释 Qt 里的 this 指针的用法。
新建一个目录 05_this_pointer_example,编辑一个 05_this_pointer_example.cpp 内容如下

1 #include <iostream>
2 #include <string>
3 using namespace std;
4
5 class Dog
6 {
7 public:
8 string name;
9 void func();
10 };
11
12 int main()
13 {
14 Dog dog;
15 dog.func();
16 return 0;
17 }
18
19 void Dog::func()
20 {
21 this->name = "旺财";
22 cout<<"小狗的名字叫:"<<this->name<<endl;
23 }


第 21 和 22 行,在类的成员函数里使用了 this 指针,并指向了类里的成员 name。先将 name赋值叫“旺财”,然后我们打印 name 的值