问题:
创建一个对象时,成员变量的初始值是多少?
从程序设计的角度,对象只是变量,因此:
-在栈上创建对象时,成员变量初始为随机值
-在堆上创建对象时,成员变量初始为随机值
-在静态存储区创建对象时,成员变量初始为0值
生活中的对象都是在初始化后上市的(比如说手机)
初始状态(出厂设置)是对象普遍存在的一个状态
问题:
程序中如何对一个对象进行初始化?
一般而言,对象都需要一个确定的初始状态
解决方案
方案一:
-在类中提供一个public的initialize函数
-对象创建后立即调用initialize函数进行初始化
代码如下:
1 #include <stdio.h>
2
3 class Test
4 {
5 private:
6 int i;
7 int j;
8 public:
9 int getI() { return i; }
10 int getJ() { return j; }
11 void initialize()
12 {
13 i = 1;
14 j = 2;
15 }
16 };
17
18 Test gt;
19
20 int main()
21 {
22 gt.initialize();
23
24 printf("gt.i = %d
", gt.getI());
25 printf("gt.j = %d
", gt.getJ());
26
27 Test t1;
28
29 t1.initialize();
30
31 printf("t1.i = %d
", t1.getI());
32 printf("t1.j = %d
", t1.getJ());
33
34 // t1.initialize();
35
36 Test* pt = new Test;
37
38 pt->initialize();
39
40 printf("pt->i = %d
", pt->getI());
41 printf("pt->j = %d
", pt->getJ());
42
43 delete pt;
44
45 return 0;
46 }
上述这种方式虽然能满足要求,但是还存在一个问题。
假如在创建了对象后,没有立即调用initialize()函数,又会怎样呢?
可以将上面的代码,第29行注掉,第34行打开,再实验一下,观察一下现象。
t1这个对象,它的成员变量i,j又是随机值了。
这种解决方案,虽然在一定程度上解决问题,但是它并不完美。既然是对象创建后就必须调用的函数,为什么initialize函数必须手工调用呢?如果是人手工调用的话,就有可能出错。要么忘记了调用,要么调用的顺序不对。所以,应该有一个大胆的想法,这个initialize函数能不能自动调用?
于是就诞生了构造函数。
C++中可以定义与类名相同的特殊成员函数
-这种特殊的成员函数叫做构造函数
构造函数没有任何返回类型的声明
构造函数在对象定义时自动被调用
1 #include <stdio.h>
2
3 class Test
4 {
5 private:
6 int i;
7 int j;
8 public:
9 int getI() { return i; }
10 int getJ() { return j; }
11 Test()
12 {
13 printf("Test() Begin
");
14
15 i = 1;
16 j = 2;
17
18 printf("Test() End
");
19 }
20 };
21
22 Test gt;
23
24 int main()
25 {
26 printf("gt.i = %d
", gt.getI());
27 printf("gt.j = %d
", gt.getJ());
28
29 Test t1;
30
31 printf("t1.i = %d
", t1.getI());
32 printf("t1.j = %d
", t1.getJ());
33
34 Test* pt = new Test;
35
36 printf("pt->i = %d
", pt->getI());
37 printf("pt->j = %d
", pt->getJ());
38
39 delete pt;
40
41 return 0;
42 }
对象创建后,构造函数就会被立即的调用执行。那么调用是谁来做的呢?
编译器在编译程序时,它会敏感的发现程序中定义了构造函数,于是在创建对象的地方帮我们自动的调用了构造函数。
小结:
每个对象在使用之前都应该初始化
类的构造函数用于对象的初始化
构造函数与类同名并且没有返回值
构造函数在对象定义时自动被调用