C++ 新特性 | C++ 11 | 列表初始化

一、列表初始化

1、C++98中{}的初始化问题

在C++98中,标准允许使用花括号{}对数组元素进行统一的列表初始值设定。比如:

int array1[] = {1,2,3,4,5};
int array2[5] = {0};

对于一些自定义的类型,却无法使用这样的初始化。比如:

vector<int> v{1,2,3,4,5};

就无法通过编译,导致每次定义vector时,都需要先把vector定义出来,然后使用循环对其赋初始值,非常不方便。

C++ 提供了多种变量初始化的方式,如等号 =、括号 ()、和大括号 {},每种方式都有其特殊的用途和限制。要选择合适的初始化方式,就需要了解它们的区别和适用情况。

2、C++ 的传统初始化方式:括号 ()

2.1、括号 () 的初始化方式和用途

在 C++ 中,括号 () 可以用于调用构造函数进行初始化,比如:

std::string s("Hello, World!");

在这个例子中,我们使用括号 () 调用了 std::string 的构造函数,用字符串字面量 “Hello, World!” 初始化了 s。这是一种直接的、明确的初始化方式。

2.2、使用括号 () 进行初始化的限制和问题

然而,C++ 的括号初始化也有其局限性。一个著名的问题是,当你试图定义一个对象,但却不小心写成了函数声明。例如,以下的 C++ 代码:

std::string s();  // Oops, 这是一个函数声明,而不是对象的定义

在这个例子中,我们可能希望定义一个 std::string 类型的对象 s,并用默认的构造函数进行初始化。然而,按照 C++ 的语法规则,这实际上是声明了一个没有参数并返回 std::string 类型的函数 s。这被称为 “最令人困惑的语法”(Most Vexing Parse)。

3、C++11列表初始化

为了解决老版本的初始化存在的问题,C++11扩大了用大括号括起的列表(初始化列表)的使用范围,使其可用于所有的内置类型和用户自定义的类型,使用初始化列表时,可添加等号(=),也可不添加。

3.1、内置类型的列表初始化

   int main() {
	// 内置类型变量 
	int x1 = {10}; 
	int x2{10}; 
	int x3 = 1+2; 
	int x4 = {1+2}; 
	int x5{1+2}; 
	// 数组
    int arr1[5] {1,2,3,4,5};
    int arr2[]{1,2,3,4,5};
    
	// 动态数组,在C++98中不支持
	int* arr3 = new int[5]{1,2,3,4,5};
	
	// 标准容器
	vector<int> v{1,2,3,4,5};
	map<int, int> m{{1,1}, {2,2},{3,3},{4,4}}; 
	return 0;
}

注意:列表初始化可以在{}之前使用等号,其效果与不使用=没有什么区别。

3.2、自定义类型的列表初始化

class Point
{
public:
    Point(int x = 0, int y = 0): 
    	_x(x), 
    	_y(y)
	{} 
private:
	int _x;
	int _y; 
};
	
int main() {
    Point p{ 1, 2 };
	return 0; 
}

注意:如果自定义的数据类型的成员在声明时初始化过,就不能使用{}进行初始化,不然编译会报错。例如:下面的代码在编译时会报错

struct Point {
    int x = 0;  // 成员声明时进行初始化
    int y = 0;
};

Point p{ 10, 20 }; // 错误	C2440	“初始化”: 无法从“initializer list”转换为“Point”	

3.3、使用大括号 {} 进行初始化的优点

列表初始化的优点之一是它可以防止窄化转换(Narrowing Conversion)。窄化转换是指一种可能会丢失信息的类型转换,比如将浮点数转换为整数,或者将大的整数转换为小的整数。如果我们试图进行窄化转换,编译器将会报错。例如,下面的 C++ 代码试图使用浮点数初始化一个整数:

int a{3.14};  // 错误:窄化转换

这段代码将无法通过编译,因为 {3.14} 试图将一个浮点数转换为整数,这是一种窄化转换。这个特性可以帮助我们避免由于窄化转换引起的潜在错误。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值