深入应用C++11学习笔记_1.3列表初始化

1.3.1 统一的初始化

C++11中,初始化列表可以用于任何类型对象的初始化。

int *a = new int {123};
double b = double { 12.12 };
int *arr = new int[3] { 1, 2, }

列表初始化可以直接用在函数的返回值上。

struct Foo
{
    Foo(int, double){}
};
Foo func(void)
{
    return { 123, 321.0 };
}
1.3.2 列表初始化的使用细节

聚合类型的定义:

  1. 类型是一个普通数组(如int[10]、char[]、long [2] [3])

  2. 类型是一个类(class、struct、union),且:

    • 无用户自定义的构造函数

    • 无私有或保护的非静态数据成员

    • 无基类

    • 无虚函数

    • 不能有 { } 和 = 直接初始化的非静态数据成员

有用户自定义的构造函数:

struct Foo
{
    int x;
    double y;
    int z;
    Foo(int, int) {}
};

Foo foo {11.51};	//error

有私有或保护的非静态成员:

struct Foo
{
    int x;
    double y;
protected:
    int z;
};

Foo foo {1, 1.5, 1};	//error
Foo foo {11.5};	//ok

有基类或者虚函数:

struct ST
{
	int x;
	double y;
	virtual void F()
};

ST st {1, 2.5};	//error

struct Base {};
struct Foo : public Base
{
    int x;
    double y;
}

Foo foo {1, 2.5};	//error

有 { } 或者 = 直接初始化的非静态成员:

struct ST
{
    int x;
    double y = 0.0;
};

ST st {1, 2.5};	//error

对于非聚合类型的初始化列表,需要自定义构造函数:

struct ST
{
    int x;
    double y;
    virtual void F() {}
private:
    int z;
public:
    ST(int i, double j, int k) : x(i), y(j), z(k) {}
};

ST st {1, 2.5, 2};	//OK

当一个类的非静态成员是非聚合类型时,这个类也有可能是聚合类型:

struct ST
{
    int x;
    double y;
private:
    int z;	//非聚合类型因为有private的非静态成员
}

struct Foo
{
    ST st;
    int x;
    double y;
};	//虽然成员ST为非聚合类型,但Foo仍然是一个聚合类型

Foo foo { {} , 1, 2.5};	//OK,相当于调用了ST的无参构造函数
1.3.3 初始化列表(std::initializer_list)

通过初始化列表给自定义容器赋值,也可以传递同类型数据的集合:

class Foo
{
private:
    std::vector<int> content;
public:
    Foo(std::initializer_list<int> list)
    {
        for(auto it = list.begin(); it != list.end(); ++it)
        {
            content.push_back(*it);
        }
    }
};

Foo foo = { 1,2,3,4,5 };

std::initializer_list的细节:

  • 是一个轻量级的容器类型,内部定义了容器必需的概念。
  • 可以接收任意长度的初始化列表,但要求元素必须是同种类型。
  • 有三个成员接口: size() , begin() , end()。
  • 遍历时取得的迭代器时只读的,列表只能被整体初始化或赋值。
  • 拥有无参构造函数,可以直接定义示例。
  • 内部并不负责保存初始化列表中元素的拷贝,只保存引用,所以不能用于存储生命周期之外的参数。解决方案:在函数中用具有转移拷贝语义的物件,真正的容器来替代std::initializer_list来返回需要的结果。
1.3.4 防止类型收窄

类型收窄:导致数据内容变化或者精度丢失的隐式类型转换。

  • 从浮点数隐式转换为整数。
  • 从高精度浮点数转换为低精度浮点数。
  • 从整数转换为浮点数,但超过了浮点数的表示范围。
  • 从整数转换为长度较短的整数。

通过列表初始化防止类型收窄:

int a = 1.1;	//OK
int a = { 1.1 };	//error
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值