1,C++ 中类的真正形态是通过 class 这个关键字来定义的;
2,对象中成员变量的初始值是多少?
1,通过下面的小实验来说明问题;
3,小实验:
1,下面的类定义中成员变量 i 和 j 的初始值是什么?
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 }; 12 13 Test gt; 14 15 int main() 16 { 17 printf("gt.i = %d ", gt.getI()); 18 printf("gt.j = %d ", gt.getJ()); 19 20 Test t1; 21 22 printf("t1.i = %d ", t1.getI()); 23 printf("t1.j = %d ", t1.getJ()); 24 25 Test* pt = new Test; // 类也是一种数据类型而已 26 27 printf("pt->i = %d ", pt->getI()); 28 printf("pt->j = %d ", pt->getJ()); 29 30 delete pt; // 释放堆空间; 31 32 return 0; 33 }
1,自定义数据类型也是数据类型,所以要遵循 C++ 语言中对数据类型的所有可用特性和操作;
2,所以可以定义一个指针指向一个类的对象;
3,类定义得到的是数据类型;
4,对象的初始化:
1,从程序设计角度,对象只是变量,因此:
1,在栈上创建对象时,成员变量初始为随机值;
2,在堆上创建对象时,成员变量初始为随机值;
3,在静态存储区(包括全局对象和 static 修饰的局部对象)创建对象时,成员变量初始值为 0 值;
2,生活中的对象都是在初始化后上市的;
3,初始状态(出厂设置)是对象普遍存在的一个状态;
4,一般而言,对象都需要一个确定的初始状态,解决方案:
1,在类中提供一个 public 的 initialize 的函数;
2,对象创建后立即调用 initialize 函数进行初始化;
5,初始化函数编程实验:
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 12 void initialize() // 对成员变量进行指定 13 { 14 i = 1; 15 j = 2; 16 } 17 }; 18 19 Test gt; 20 21 int main() 22 { 23 gt.initialize(); // 创建对象后需要立即显示调用 24 25 printf("gt.i = %d ", gt.getI()); 26 printf("gt.j = %d ", gt.getJ()); 27 28 Test t1; 29 30 //t1.initialize(); // 创建对象后需要立即显示调用 31 32 printf("t1.i = %d ", t1.getI()); 33 printf("t1.j = %d ", t1.getJ()); 34 35 t1.initialize(); // 创建对象后需要立即显示调用,在之后调用就不可以了 36 37 Test* pt = new Test; 38 39 pt->initialize(); // 创建对象后需要立即显示调用 40 41 printf("pt->i = %d ", pt->getI()); 42 printf("pt->j = %d ", pt->getJ()); 43 44 delete pt; 45 46 return 0; 47 }
6,存在的问题:
1,initialize 只是一个普通函数,必须显示调用;
2,如果未调用 initialize 函数,运行结果是不确定的;
3,要么忘记调用,要么调用顺序出错,是否可以创建了之后自动调用;
5,构造函数:
1,C++ 中可以定义与类名相同的特殊成员函数,这种特殊的成员函数叫做构造函数:
1,构造函数没有任何返回类型的声明;
2,构造函数在对象定义时自动被调用;
2,构造函数初探编程实验:
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 12 Test() // 无返回值,名字和类名相同,这是特殊之处;相对于普通函数功能在于在类创建的时候自动调用; 13 { 14 printf("Test() Begin "); 15 16 i = 1; 17 j = 2; 18 19 printf("Test() End "); 20 } 21 }; 22 23 Test gt; 24 25 int main() 26 { 27 printf("gt.i = %d ", gt.getI()); 28 printf("gt.j = %d ", gt.getJ()); 29 30 Test t1; 31 32 printf("t1.i = %d ", t1.getI()); 33 printf("t1.j = %d ", t1.getJ()); 34 35 Test* pt = new Test; 36 37 printf("pt->i = %d ", pt->getI()); 38 printf("pt->j = %d ", pt->getJ()); 39 40 delete pt; 41 42 return 0; 43 }
1,实验结果说明,对象创建之后,构造函数就会被立即的调用执行;
2,编译器在编译程序的时候,会敏感的发现我们定义了构造函数,于是在创建对象的地方,就敏感的为我们自动调用了;
6,小结:
1,每个对象在使用之前都应该初始化;
1,初始化在面向对象当中的术语叫构造;
2,类的构造函数用于对象的初始化;
3,构造函数与类同名并且没有返回值;
4,构造函数在对象定义时自动被调用;