对象的构造(上)

类是一种特殊的自定义类型,自定义类型遵守C语言中所有数据类型的操作,也可以用来定义指针,这种特殊的自定义类可以用来定义变量,从面向对象的角度就是实例化一个对象了,从程序的本质上来将就是定义一个自定义类型的变量,既然是变量它就需要占用存储空间,占用什么区域的存储空间和C语言中的说法一致,即局部变量在栈空间,全局变量在静态存储区(.bss 和 .data段)
例子:

#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;
}

编译结果:

sice@sice:~/DT$ g++ a.cpp
sice@sice:~/DT$ ./a.out 
gt.i = 0
gt.j = 0
t1.i = 0
t1.j = 134514073
pt->i = 0
pt->j = 0

可以知道t1就是局部变量,它占用的空间在栈上面,既然它在栈上面占用了存储空间,它的成员变量又没有初始值,自然它们的初始值就不确定了,gt对象在是个全局变量初始化为0,new跟C语言中的malloc大同小异,本质上也是向堆空间申请内存,pt指向堆空间里面申请的Test类型的对象,在我们之前学习中在堆空间得到的变量的初始值是不定的,这里为0只是g++编译器在linux平台下的优化,delete相当于free,用于堆空间的释放
在这里插入图片描述
一般而言,对象都需要一个确定的初始化状态(类似手机类里面的iphone4s对象有出厂设置的初始状态一样),我们怎么使得无论在哪里创建对象,对象的成员的初始值都为0呢?
解决方案
在类中提供一个public的initialize函数
对象创建后立即调用initialize函数进行初始化

#include <stdio.h>

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

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());
    
    t1.initialize();
    
    Test* pt = new Test;
    
    pt->initialize();
    
    printf("pt->i = %d\n", pt->getI());
    printf("pt->j = %d\n", pt->getJ());
    
    delete pt;
    
    return 0;
}

优化方案
我们的initialize函数必须在对象创建后就调用,那就存在人工的疏忽,我们需要将它自动化,所以C++里面提供了构造函数,构造函数的函数名与类名相同,构造没有任何返回类型的声明,构造函数在对象定义时自动被调用
代码:

#include <stdio.h>
class Test
{
   private:
      int i;
      int j;
   public:
      int getI(void){return i;}
      int getJ(void){return j;}
   Test()
   {  
      printf("Test() Begin\n");
      i = 2;
      j = 1;
      printf("Test() End\n");
   }
};
Test a;
int main(void)
{
    printf("a.i = %d\n", a.getI());
    printf("a.j = %d\n", a.getJ());
    
    Test b;
    
    printf("b.i = %d\n", b.getI());
    printf("b.j = %d\n",b.getJ());
    
    Test* c = new Test;
    
    printf("c->i = %d\n", c->getI());
    printf("c->j = %d\n", c->getJ());
    
    delete c;
    
    return 0; 



}

结果:

sice@sice:~/DT$ ./a.out 
Test() Begin
Test() End
a.i = 2
a.j = 1
Test() Begin
Test() End
b.i = 2
b.j = 1
Test() Begin
Test() End
c->i = 2
c->j = 1


发布了20 篇原创文章 · 获赞 1 · 访问量 359

猜你喜欢

转载自blog.csdn.net/qq_41936794/article/details/104535024