问题: 对象中成员变量的初始值是多少?

小实验

下面的类定义中成员变量 i 和 j 的初始值为什么?

class Test
{
private:
    int i;
    int j;
public:
    int getI() { return i; };
    int getJ() { return j };
};

编程实验: 成员变量的初始值

#include <stdio.h>

class Test
{
private:
    int i;
    int j;
public:
    int getI() { return i; };
    int getJ() { return j; };
};

Test gt;

int main()
{
    printf("gt.i = %d\n", gt.getI());
    printf("gt.j = %d\n", gt.getJ());
    
    Test t1;
    printf("t1.i = %d\n", t1.getI());
    printf("t1.j = %d\n", t1.getJ());
    
    Test* pt = new Test;
    
    printf("pt->i = %d\n", pt->getI());
    printf("pt->j = %d\n", pt->getJ());
    
    delete pt;
    
    return 0;
}
输出:
gt.i = 0
gt.j = 0
t1.i = 12467072
t1.j = 134514539
pt->i = 0
pt->j = 0

对象的初始化

  • 从程序设计的角度,对象只是变量,因此:

    • 在栈上创建对象时,成员变量初始值为随机值
    • 在堆上创建对象时,成员变量初始值为随机值
    • 在静态存储区创建对象时,成员变量初始值为 0

  • 生活中的对象都是在初始化后上市的
  • 初始状态(出厂设置)是对象普遍存在的一个状态

问题:程序中如何对一个对象进行初始化?

  • 一般而言,对象都需要一个确定的初始状态
  • 解决方案

    • 在类中提供一个 public 的initialize 函数
    • 对象创建立即调用 initialize 函数进行初始化
class Test
{
private:
    int i;
    int j;
public:
    void initialize() { i = 0; j = 0; };
    int getI() { return i; };
    int getJ() { return j; };
};

编程实验: 初始化函数

#include <stdio.h>

class Test
{
private:
    int i;
    int j;
public:
    void initialize() { i = 0; j = 0; };
    int getI() { return i; };
    int getJ() { return j; };
};

Test gt;

int main()
{
    gt.initialize();
    printf("gt.i = %d\n", gt.getI());
    printf("gt.j = %d\n", gt.getJ());
    
    Test t1;
    t1.initialize();
    printf("t1.i = %d\n", t1.getI());
    printf("t1.j = %d\n", t1.getJ());
    
    Test* pt = new Test;
    pt->initialize();
    printf("pt->i = %d\n", pt->getI());
    printf("pt->j = %d\n", pt->getJ());
    
    delete pt;
    
    return 0;
}
输出:
gt.i = 0
gt.j = 0
t1.i = 0
t1.j = 0
pt->i = 0
pt->j = 0
  • 存在的问题

    • initialize 只是一个普通函数,必须显示调用
    • 如果未调用 initialize 函数,运行结果是不确定的

构造函数

  • C++ 中可以定义与类名相同的特殊成员函数

    • 这种特殊的成员函数叫做构造函数

      • 构造函数没有任何返回类型的声明
      • 构造函数在对象定义时被自动调用

编程实验: 构造函数初探

#include <stdio.h>

class Test
{
private:
    int i;
    int j;
public:
    int getI() { return i; };
    int getJ() { return j; };
    
    Test()
    {
        printf("Test Begin ...\n");
        i = 1; 
        j = 2;
        printf("Test End ...\n");
    }
};

Test gt;

int main()
{
    printf("gt.i = %d\n", gt.getI());
    printf("gt.j = %d\n", gt.getJ());
    
    Test t1;
    printf("t1.i = %d\n", t1.getI());
    printf("t1.j = %d\n", t1.getJ());
    
    Test* pt = new Test;
    printf("pt->i = %d\n", pt->getI());
    printf("pt->j = %d\n", pt->getJ());
    
    delete pt;
    
    return 0;
}
输出:
Test Begin ...
Test End ...
gt.i = 1
gt.j = 2
Test Begin ...
Test End ...
t1.i = 1
t1.j = 2
Test Begin ...
Test End ...
pt->i = 1
pt->j = 2

小结

  • 每个对象在使用之前都应该初始化
  • 类的构造函数用于对象的初始化
  • 构造函数与类同名并且没有返回值
  • 构造函数在对象定义时自动被调用

以上内容参考狄泰软件学院系列课程,请大家保护原创!


TianSong
737 声望139 粉丝

阿里山神木的种子在3000年前已经埋下,今天不过是看到当年注定的结果,为了未来的自己,今天就埋下一颗好种子吧