关于最近看到的关于类的初始化的问题,我觉得有必要在这里讲一下,可能平时不注意的话,就有可能犯错。
看下面的代码:
#include "stdafx.h"
#include<iostream>
using namespace std;
class X
{
int i;
int j;
public:
X(){};
X(int val)
: i(j),
j(val)
{cout<<"init is successful!\n";}
void put()
{
printf("i = %d, j=%d\n", i, j);
return ;
}
};
int _tmain(int argc, _TCHAR* argv[])
{
X a = X(5);
a.put();
return 0;
}
在这段代码中,变量i在变量之前声明,那么在类X的构造函数初始化成员列表中,变量i会先定义,变量j会后定义,也就是说变量i会先初始化,而变量j会后初始化,所以,在执行
X(int val)
: i(j),
j(val)时,i的值用j来初始话,其结果将是一个随机值,而j的值是5,下面是其结果:
在将变量i和j的声明顺序换一下后,其结果会发生变化,新的源代码是:
#include "stdafx.h"
#include<iostream>
using namespace std;
class X
{
int j;
int i;
public:
X(){};
X(int val)
: i(j),
j(val)
{cout<<"init is successful!\n";}
void put()
{
printf("i = %d, j=%d\n", i, j);
return ;
}
};
int _tmain(int argc, _TCHAR* argv[])
{
X a = X(5);
a.put();
return 0;
}
其编译后的结果是:
此时,就得到了所希望的确定的初始值,当然程序中的写法欠妥,好的写法应该是:
#include "stdafx.h"
#include<iostream>
using namespace std;
class X
{
int j;
int i;
public:
X(){};
X(int val)
: i(val),
j(val)
{cout<<"init is successful!\n";}
void put()
{
printf("i = %d, j=%d\n", i, j);
return ;
}
};
int _tmain(int argc, _TCHAR* argv[])
{
X a = X(5);
a.put();
return 0;
}
当然,最后的结果和上面是一样的,这也就告诉我们:按照与成员变量声明一致的次序来编写构造函数初始化列表是个好主意,此外,尽可能避免使用成员来初始化其他成员,一般情况下,通过(重复)使用构造函数的形参而不是使用对象的数据成员,可以避免由初始化的执行次序而引起的任何问题。