C++中的值初始化和默认初始化

1、值初始化

      顾名思义,就是用数值初始化变量。如果没有给定一个初始值,就会根据变量或类对象的类型提供一个初始值。对于int类型其值初始化后的值为0。

2、默认初始化:如果定义变量时没有指定初值,则变量被默认初始化。其初始值和变量的类型以及变量定义的位置相关。默认初始化类对象和默认初始化内置类型变量有所不同。

对于默认初始化内置类型变量来说:

      1)定义在函数体之外的变量是全局变量,一般存储在全局区,存储在全局区的变量一般会执行值初始化。此时,其初始值和变量的类型有关。对于int类型其初始值为0,对于char类型其默认初始值为' '。例子如下:

#include <iostream>

using namespace std;

int i;
double d;
char c;

int main() 
{
	cout << "i = " << i << endl;
	cout << "d = " << d << endl;
	cout << "char" << c << "char" << endl;

	system("pause");
	return 0;
}

在VS2015中编译结果如下:

      2)定义在函数体内部的是局部变量,其存储在栈区中,如果使用默认初始化(没有指定初值),那么该局部变量将不会被初始化,也就是说这个局部变量的值是未定义的,是个随机值。此时,如果不给这个局部变量赋值,那么就不能使用该局部变量,否则就会出错。例子如下:

#include <iostream>

using namespace std;

int main() 
{
	int i;
	cout << "i = " << i << endl;

	system("pause");
	return 0;
}

在VS2015中编译结果如下:

对于默认初始化类对象来说:不仅在创建类对象时,要使用默认构造函数,而且类成员要没有类内初始值,类才会执行默认初始化。

      如果是自定义的默认构造函数,不进行任何操作或者是编译器合成的默认构造函数,其成员变量经过默认初始化之后的初始化值和局部变量的初始值是一样的,即是随机值,但是可以使用(类普通成员变量也存在栈区)。例子如下:

#include <iostream>
#include <string>

using namespace std;

class Init 
{
public:
	int getA() 
	{
		return a;
	}
	double getD()
	{
		return d;
	}
	char getC()
	{
		return c;
	}
	string getStr()
	{
		return str;
	}

private:
	int a;
	char c;
	double d;
	string str;
};

int main() 
{
	Init init;
	
	cout << "a = " << init.getA() << endl;
	cout << "d = " << init.getD() << endl;
	cout << "ccc" << init.getC() << "ccc" << endl;
	cout << "str" << init.getStr() << "str" << endl;

	system("pause");
	return 0;
}

在VS2015中编译结果如下:

对于string类型的成员变量是个空串,这可能和string类的内部实现有关。

3、默认初始化的出现场景。

     1)当我们在块作用域内不使用任何初始值定义一个非静态变量或者数组时。数组和非静态变量它们的值都是随机值,但是数组可以使用,而非静态变量需要在赋值以后才能使用。例子如下;

#include <iostream>

using namespace std;

int main()
{
	int a[5];

	for (int i = 0; i < 5; i++)
	{
		cout << "数组元素值为:" << a[i] << endl;
	}

	system("pause");
	return 0;
}

在VS2015下编译结果如下:

    2)当一个类本身含有类类型的成员且使用合成的默认构造函数时。使用合成的默认构造函数那么该类和其类类型成员都会执行默认初始化。

    3)当类类型的成员没有在构造函数初始值列表中显示地初始化时。说明该类类型成员会调用默认构造函数。

4、值初始化的出现场景

    1)在数组初始化的过程中如果我们提供的初始值数量少于数组的大小时,剩余的为提供初始值部分就会执行值初始化。

#include <iostream>

using namespace std;

int main()
{
	int a[5] = {1, 2, 3};

	for (int i = 0; i < 5; i++)
	{
		cout << "数组元素值为:" << a[i] << endl;
	}

	system("pause");
	return 0;
}

在VS2015下编译结果如下:

由结果可知,没有提供初始值的数组元素按照值初始化为了0。

    2)当我们不使用初始值定义一个局部静态变量时。因为是静态的,所以该局部静态变量不再存储在栈区,而是存储在全局区。此时,就会根据类型进行设置该变量的初始值,即值初始化。例子如下:

#include <iostream>

using namespace std;

int main()
{
    static int a;
	static char c;

	cout << "a:" << a << endl;
	cout << "ccc" << c << "ccc" << endl;	

	system("pause");
	return 0;
}

VS2015编译结果为:

    3)当我们通过书写形如T()的表达式显示请求值初始化时,其中T是类型名(vector的一个构造函数只接受一个实参用于说明vector的大小),它就是使用一个这种形式的实参来对它的元素初始器继续值初始化)。

===》》》对于默认初始化,可以参考《C++ primer》P40页

===》》》对于值初始化,可以参考《C++ primer》P88页

===》》》对于默认初始化和值初始化的发生场景,可以参考《C++ primer》P262页

===》》》对于值初始化,可以参考《C++ primer》P88页

===》》》对于合成的默认构造函数,可以参考《C++ primer》P235页

猜你喜欢

转载自blog.csdn.net/J_H_C/article/details/83589282
今日推荐