C++中对变量进行初始化的3种方法

本文详细介绍了C++中的几种初始化方式,包括拷贝初始化、构造函数初始化、直接初始化和统一初始化,以及它们在效率、语法和潜在问题上的区别。还讨论了值初始化和零初始化的应用场景,强调了列表初始化的规范和避免数据丢失的重要性。
摘要由CSDN通过智能技术生成

      1.用"=":copy initialization,这种初始化形式是从C继承的。此种方式(拷贝初始化)的初始化在现代C+中已不再受欢迎,因为对于某些复杂类型来说,此种方式初始化的效率低于其它形式的初始化。
      每当隐式拷贝或转换值时,也会使用拷贝初始化,例如按值将参数传递给函数、按值从函数返回或按值捕获异常时。

      2.构造函数初始化:通过括号(parentheses)提供值来声明变量。构造函数初始化和旧的普通初始化方式(=)的区别在于,它总是返回括号中的最后一个值,无论它的大小或符号是什么。
      direct initialization:就像拷贝初始化一样,直接初始化在现代C++中已经不再受欢迎,很大程度上是因为被列表初始化所取代。然而,我们现在知道列表初始化有其自身的一些怪癖,因此直接初始化在某些情况下再次得到使用。
      当值显式转换为另一种类型时,也会使用直接初始化。
      直接初始化不受欢迎的原因之一是它使得很难区分变量和函数:

int x();  // forward declaration of function x
int x(0); // definition of variable x with initializer 0

      3.统一初始化(list initialization or uniform initialization or brace initialization):C++中初始化对象的现代方法用大括号代替括号(curly braces instead of parentheses)。与构造函数初始化不同,此赋值方法只能采用大括号中的一个值,提供多个值将返回编译错误。
      列表初始化还有一个额外的好处:列表初始化中的"缩小转换(narrowing conversions,是隐式转换)"格式不正确。这意味着,如果你尝试使用变量无法安全保存的值来初始化变量,则编译器需要生成诊断信息(通常是错误)。
      拷贝和直接初始化只会删除小数部分,从而导致值初始化为可变宽度。你的编译器可能会选择性地警告你这一点,因为很少希望丢失数据。但是,通过列表初始化,编译器需要在这种情况下生成诊断。
      你可以在通常进行初始化的任何地方使用大括号初始化,例如,作为函数参数或返回值,或者与new关键字一起使用。
      Value initialization and zero initialization: 当使用空大括号初始化变量时,将进行值初始化。在大多数情况下,值初始化会将变量初始化为零(或空,如果这更适合给定类型)。在发生归零的情况下,这称为归零初始化。
      什么时候应该使用{0}和{}进行初始化
      (1).如果你实际使用该值,请使用显式初始化值。
      (2).如果值是临时的并且将被替换,请使用值初始化。

      优先选择直接列表初始化(或值初始化)来初始化变量

      以下为测试代码,进行了描述说明

int test_variables_init()
{
	int val; // no initializer(default initialization): 在大多数情况下,默认初始化不执行初始化,并且使变量具有不确定的值


	// 1.using "="
	int val1 = 1; // copy initialization: 这种初始化形式是从C继承的
	std::cout << "val1:" << val1 << "\n"; // val1:1


	// 2.constructor initialization: parentheses
	int val2(2); // direct initialization
	std::cout << "val2:" << val2 << "\n"; // val2:2

	int val3 = (3);
	std::cout << "val3:" << val3 << "\n"; // val3:3

	// 构造函数初始化和旧的普通初始化方式(=)的区别在于,它总是返回括号中的最后一个值,无论它的大小或符号是什么
	int val4 = (4, 5, 6, 7, -8);
	std::cout << "val4:" << val4 << "\n"; // val4:-8


	// 3.uniform initialization: curly braces
	int val5{ 9 }; // direct list initialization
	std::cout << "val5:" << val5 << "\n"; // val5:9

	int val6 = { 10 }; // copy list initialization
	std::cout << "val6:" << val6 << "\n"; // val6:10

	// 与构造函数初始化不同,统一初始化方法只能采用大括号中的一个值,提供多个值将返回编译错误
	//int val7 = { 11, 12 }; // error C2440: "初始化": 无法从"initializer list"转换为"int"

	int val8{}; // value initialization
	int val12{ 0 }; // explicit initialization to value 0
	std::cout << "val8:" << val8 << "\n"; // val8:0

	// 列表初始化中的"缩小转换(narrowing conversions)"格式不正确
	//int val9{ 4.5 }; // error C2397: 从"double"转换到"int"需要收缩转换
	int val10 = 4.5; // warning C4244: "初始化": 从"double"转换到"int",可能丢失数据
	int val11(4.5); // warning C4244: "初始化": 从"double"转换到"int",可能丢失数据

	return 0;
}

      执行结果如下图所示:

      GitHubhttps://github.com/fengbingchun/Messy_Test

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值