前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >C++11标准常用特性---统一初始化

C++11标准常用特性---统一初始化

作者头像
Sky_Mao
发布2020-07-24 10:17:50
6850
发布2020-07-24 10:17:50
举报

1、在给结构体赋值的时候,可以使用一对大括号来进行赋值,赋值过程中会按照结构体成员顺序来进行赋值;

代码语言:javascript
复制
struct initTest
{
    int nNum;
    string str;
};

initTest o = { 1, "初始化" }; //第一种初始化方式
initTest o2{ 1, "初始化" };   //第二种初始化方式

初始化的类型是否按照顺序指定的呢? 传入一个错误的类型试试,看下编译器会提示什么。

错误提示.png

从编译器的错误提示中可以看到,第一个参数类型已经被确定为int类型。

2、初始化列表初始化类

代码语言:javascript
复制
class initClass
{
public:
    initClass(int nC, string str) {};
};

initClass o = { 2, "初始化" }; //第一种初始化方式
initClass o2{ 1, "初始化" };   //第二种初始化方式

3、初始化同类型不定个数参数

C++11把初始化列表的概念绑到一个叫做std::initializer_list的模板上,这允许构造函数或其他函数将初始化列表做为参数.例如:

代码语言:javascript
复制
template<class T>
class initClass
{
public:
    initClass(initializer_list<T> initList) {};
};

initializer_list<int> oList{ 1, 2, 3, 4, 5, 6, 7 };
initClass<int> o{ oList };

initializer_list<double> oListd{ 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0 };
initClass<double> oD{ oListd };

这个构造函数是一种特殊的构造函数,叫做初始化列表构造函数(initializer-list-constructor)

\color{#FF3030}{类型std::initializer_list<>是个第一级的C++11标准程序库类型,但是,它们只能由C++11通过\{\}}
\color{#FF3030}{类型std::initializer_list<>是个第一级的C++11标准程序库类型,但是,它们只能由C++11通过\{\}}
\color{#FF3030}{这个列表一经构造便可复制,虽然这只是copy-by-reference。初始化列表是常数;}
\color{#FF3030}{这个列表一经构造便可复制,虽然这只是copy-by-reference。初始化列表是常数;}
\color{#FF3030}{一旦被创建,其成员均不能被改变,成员中的数据也不能够被改变。}
\color{#FF3030}{一旦被创建,其成员均不能被改变,成员中的数据也不能够被改变。}

函数统一类型入参也可以使用:

代码语言:javascript
复制
void FunctionName(initializer_list<float> list);  
FunctionName({1.0f, -3.45f, -0.4f}); 

4、标准容器的统一初始化

C++11之前初始化一个vector,需要调用多次push_back函数进行初始化。

代码语言:javascript
复制
vector<double> oDList;
oDList.push_back(1.0);
oDList.push_back(2.0);

C++11可以这么实现:

代码语言:javascript
复制
vector<double> oDList{ 1.0, 2.0 };
vector<double> oDList = { 1.0, 2.0 };
vector<double> oDList({ 1.0, 2.0 });
\color{#FF3030}{注意:这种方式初始化不同与add,所以循环内初始化还是需要使用push_back函数的。}
\color{#FF3030}{注意:这种方式初始化不同与add,所以循环内初始化还是需要使用push_back函数的。}

5、非静态类成员赋值

C++11之前只有静态成员在声明的时候可以赋初值。C++11让非静态成员也可以在声明的时候赋值。

代码语言:javascript
复制
class initClass
{
public:
    initClass() {};
private:
    int m_nC = 0;
    string m_str = "";
};

如果初始化列表对类initClass的两个赋过初值的成员变量进行了另外的初始化,那么赋值的内容会被覆盖。 小测试一下: 修改代码如下:

代码语言:javascript
复制
class initClass
{
public:
    initClass(const int nC, const string str) : m_nC(nC), m_str(str) {};

    int getNc() { return m_nC; };
    string getStr() { return m_str; };
private:
    int m_nC = 0;
    string m_str = "";
};

initClass test1{ 10, "test" };
cout << "initClass::m_nC:\t" << test1.getNc() << endl;
cout << "initClass::m_str:\t" << test1.getStr() << endl;

测试结果:

测试结果.png

6、对象构造的改进

C++11以前类的构造函数不允许调用该类的其它构造函数;每个构造函数都必须自己或者调用一个公共的成员函数来构造类的全部成员.例如:

代码语言:javascript
复制
class SomeType1
{
public:
    SomeType1(int new_number) : number(new_number) {}
    SomeType1() : number(42) {}
private:
    int number;
};

class SomeType2 
{
public:
    SomeType2(int new_number) { init(new_number); } //必须调用一个公共初始化函数进行初始化成员
    SomeType2() { init(42); }
private:
    void init(int new_number) { number = new_number; }

private:
    int number;
};

而且,基类的构造函数不能直接暴露给派生类;每个派生类必须实现自己的构造函数哪怕基类的构造函数已经够用了.非静态数据成员不能在声明的地方初始化.它们只能在构造函数中初始化. C++11为这些问题提供了解决方案.C++11允许构造函数调用另一个构造函数(叫做委托构造).这允许构造函数利用其它构造函数的行为而只需增加少量的代码.C#,java和D语言都提供了这种功能. C++的语法如下:

代码语言:javascript
复制
class SomeType1
{
public:
    SomeType1(int new_number) : number(new_number) {}
    SomeType1() : SomeType1(42) {}
private:
    int number;
};

注意:这个例子可以通过给new_number设定一个默认参数来达到相同的效果.但是,这种新语法可以让这个默认值在实现中来设置而不是在接口中设置.这带来的一个好处就是,对库代码的维护者而言,在接口中(头文件中)声明默认值,这个默认值被嵌入到了调用端;要改变这个默认值的话,调用端的代码都需要重新编译.但委托构造可以在实现中(CPP文件中)来改变这个默认值, 这样调用端的代码就不需要重新编译,只用重新编译这个库就可以了.

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1、在给结构体赋值的时候,可以使用一对大括号来进行赋值,赋值过程中会按照结构体成员顺序来进行赋值;
  • 2、初始化列表初始化类
  • 3、初始化同类型不定个数参数
  • 4、标准容器的统一初始化
  • 5、非静态类成员赋值
  • 6、对象构造的改进
相关产品与服务
容器服务
腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档