欢迎来到代码驿站!

C代码

当前位置:首页 > 软件编程 > C代码

C++11系列学习之列表初始化

时间:2022-12-24 13:51:38|栏目:C代码|点击:

前言:

由于旧标准初始化方式太过繁杂,限制偏多,因此在新标准中统一了初始化方式,为了让初始化具有确定的效果,于是提出了列表初始化概念。

旧标准初始化方式

普通数组初始化:

int i_arr[3] = {1, 2, 3}

POD类型初始化(即plain old data类型,可以直接使用memcpy复制的对象):

struct A
{
int x;
struct B
{
int i;
int j;
} b;
} a = {1, {2, 3}};

拷贝初始化:

int i = 0;
class Foo
{
public:
Foo(int) {}
} foo = 123

直接初始化:

int j(0)
Foo bar(123)

C++11标准初始化方式

C++11标准中{}的初始化方式是对聚合类型的初始化,是以拷贝的形式来赋值的。

C++11标准中对非聚合类型则以构造函数来进行初始化的。

聚合类型:

  • 类型是一个普通的数组
  • 类型是一个类,

并且满足以下条件:

  • 无用户自定义的构造函数
  • 无私有或保护的非静态数据成员
  • 无基类
  • 无虚函数
  • 不能有 { } 和 = 直接初始化的非静态数据成员

初始化列表技术细节

观察下面这两个:

int arr[] {1, 2, 3}
std::set<int> ss = {1, 2, 3}

之所以可以实现STL中不指定个数进行初始化,依赖的就是与i个轻量级的类模板,也是C++11中的新特性std::initializer_listinitializer_list使用

class FooVector
{
std::vector<int> content_;
public:
FooVector(std::initializer_list<int> list){ //重要技术点
for(auto it = list.begin(); it != list.end(); ++it){
content_.back(*it)
}
}
}
FooVector foo_1 = {1, 2, 3, 4, 5} //不仅可以这样
FooVector foo_2({1, 2, 3, 4, 5}) //还可以传一个同种类型数据集合

initializer_list的特点:

  • 它是一个轻量级的容器类型,内部定义了iterator等容器必需的概念
  • 对于std::initializer_list来说,它可以接收任意长度的初始化列表,但要求元素类型必须是同种类型T(或者可转换为T)
  • 它有3个成员接口:size () 、 begin() 、end()
  • 它只能被整体初始化或赋值

注意:std::initializer_list 是非常高效的,因此内部并不负责保存初始化列表中的元素的拷贝,而是仅仅存储列表中元素的引用!因此不能用来返回临时变量!

避免类型收窄:

C++有隐式类型转换的特性,比如将一个浮点数赋值给一个整数,精度会丢失,小数点后会被直接截断。初始化列表可以帮助避免隐式类型转换。因为其不允许这种转换发生。

但是也会随着编译器的不同而不同:

float ff = 1.2
float ff = {1.2}

在gcc4.8下没有警告和错误,但Microsoft Visual C++2013中,收到编译错误。因为1.2默认是double类型,由double转换成float会发生隐式类型转换,但是并没有发生精度损失

总结

C++11新增的初始化方式,为程序的编写带来了很多的便利,这也是新标准秉承的思想和改进的方向。

上一篇:C语言平衡二叉树真题练习

栏    目:C代码

下一篇:C语言实现生成新春福字的示例详解

本文标题:C++11系列学习之列表初始化

本文地址:http://www.codeinn.net/misctech/222112.html

推荐教程

广告投放 | 联系我们 | 版权申明

重要申明:本站所有的文章、图片、评论等,均由网友发表或上传并维护或收集自网络,属个人行为,与本站立场无关。

如果侵犯了您的权利,请与我们联系,我们将在24小时内进行处理、任何非本站因素导致的法律后果,本站均不负任何责任。

联系QQ:914707363 | 邮箱:codeinn#126.com(#换成@)

Copyright © 2020 代码驿站 版权所有