摘要:在C++11之后,声明时初始化->初始化列表->构造函数初始化。

本文分享自华为云社区《如何编写高效、优雅、可信代码系列(3)——类成员初始化的三种方式》,原文作者:我是一颗大西瓜。

首先,先得了解一下C++支持哪几种类成员初始化的方式,你常用的又是哪一种。

  • 初始化方式一:初始化列表
class A
{
public:int a; // 初始化列表A(int a_):a(a_){}
};
  • 初始化方式二:构造函数初始化
class A
{
public:int a; // 初始化列表A(int a_, bool b) { a = a_; }
};
  • 初始化方式三:声明时初始化(也称就地初始化,c++11后支持)
class A
{
public:int a = 1; // 声明时初始化A() {}
};

在C++98中,支持了在类声明中使用等号“=”加初始值的方式,来初始化类中静态成员常量。这种声明方式我们也称之为“就地”声明。就地声明在代码编写时非常便利,不过C++98对类中就地声明的要求却非常高。如果静态成员不满足常量性,则不可以就地声明,而且即使常量的静态成员也只能是整型或者枚举型才能就地初始化。而非静态成员变量的初始化则必须在构造函数中进行。比如,如下代码在c++98中编译

class Init
{
public:Init(): a(0) []Init(int d): a(d) {}
private:int a;const static int b = 0;int c = 1;           // member, cannot pass buildstatic int d = 0;    // member, cannot pass buildstatic const double e = 1.3;      // not int or enum type, cannot pass buildstati const char* const f = "e";  // not int or enum type, cannot pass build
}

这非常不方便,所以在C++11中,标准允许非静态成员变量的初始化有多种形式。具体而言,除了初始化列表外,在C++11中,标准还允许使用等号= 或者 花括号{} 进行就地的非静态成员变量初始化。

struct init {int a = 1;double b {1.2};
};

大家知道,有几种情况下推荐优先使用列表初始化

  • const成员变量只能用成员初始化列表来完成初始化,而不能在构造函数内赋值
  • 初始化的数据成员是对象
  • 需要初始化引用成员数据

具体的原因这里不细述,大家可以去看一下《C++ Primer》。

构造函数初始化的本质是赋值操作("="),这个方法存在两个问题,一个是比起初始化列表和就地初始化,此方式的效率偏低;第二个是可能存在错误隐患。

先说第一个,赋值过程中会产生临时对象,临时对象的构造析构会造成效率损耗,初始化列表的方式就避免了产生临时对象缩带来的问题。

第二个是,如果你没有重写或者禁止赋值构造函数,c++会悄悄的加上默认的赋值构造函数,这个时候也有可能带来问题。

从C++11之后,这三种初始化的方法都可以使用,并不会存在冲突,但是,他们之间是有优先级顺序的,这个优先级来源于他们在初始化的时间顺序,后面初始化的会把前面的覆盖掉,成员变量的初始化顺序是

声明时初始化->初始化列表->构造函数初始化

因此假如三种初始化方式同时存在的话,那么最后保留的成员变量值肯定是构造函数中初始化的值。

#include <iostream>
using namespace std;
class A
{
public:int a = 1;A(int a_) :a(2) { a = 3; }
};int main()
{A a;cout << "a.a=" << a.a << endl;return 0;
}// a.a=3

既然初始化方式这么多,那么什么时候适用哪种呢?

1. 声明时初始化的使用场景

  • 一个优点是直观,你在声明的时候顺便给一个初始值,bravo,别人在看你代码的时候,点一下调到声明也能看到你赋予的初始值,不用再去看构造函数那里给的什么值
  • 第二个优点更有用了,比如你要定义多个构造函数,每个构造函数都用列表初始化的方法初始化,多麻烦呀,请看下面的例子,妈妈看了再也不用担心我想用其他初始化方法了
class Group {
public:Group() {}Group(int a): data(a) {}Group(Mem m): mem(m) {}Group(int a, Mem m, string n): data(a), mem(m), name(n) {}
private:int data = 1;Mem mem{0};string name{"Group"};
};

2. 列表初始化的使用场景

前面说过了三个场景,这里赘述一下

  • const成员变量只能用成员初始化列表来完成初始化,而不能在构造函数内赋值
  • 初始化的数据成员是对象
  • 需要初始化引用成员数据

但是,需要注意列表初始化的顺序,不过IDE会提示你的

3. 构造函数初始化的使用场景

  • 第一个就是拷贝和赋值构造函数里(不然怎么叫赋值构造函数呢)
  • 第二个就是比较无聊的情况了,比如你想把几个成员函数都初始化成一个值,请看下面例子
class Group {
public:Group() {data1 = data2 = data3 = 0;}
private:int data1;int data2;int data3;
};

一言以蔽之,优先就地初始化和列表初始化。

点击关注,第一时间了解华为云新鲜技术~

带你掌握C++中三种类成员初始化方式相关推荐

  1. Stateflow中三种状态转移方式的区别(默认转移、外部转移、内部转移)

    文章目录 前言 一.让人头秃的自增循环 二.默认转移和内部转移的区别 三.抛弃during追求entry 总结 前言 Stateflow中有三种典型的状态转移方式:默认转移.外部转移.内部转移. 其中 ...

  2. c++类成员初始化方式

    转载自: https://blog.csdn.net/coder_xia/article/details/7447822 常用的初始化可能如下: 1)赋值初始化 class Student { pub ...

  3. Java中final变量的初始化方式

    原文转自:http://blog.csdn.net/zhangjk1993/article/details/24196847 1 public class FinalTest1 { 2 //----- ...

  4. Java中关于数组的初始化方式

    在讲之前,先做一个选择题测试一下:关于数组的初始化方式,以下选项正确的有哪些( ) A.int[] arr = new int[5]; B.int[] arr = {10,20,30}; C.doub ...

  5. python爬虫中三种数据解析方式

    一.正解解析 常用正则表达式: 单字符: .: 除换行以外所有字符 []:[aoe] [a-w]匹配集合中任意一个字符 \d:数字 [0-9] \D: 非数字 \w :数字.字母.下划线.中文 \W ...

  6. JS中三种字符串连接方式及其性能比较

    工作中经常会碰到要把2个或多个字符串连接成一个字符串的问题,在JS中处理这类问题一般有三种方法,这里将它们一一列出顺便也对它们的性能做个具体的比较. 第一种方法  用连接符"+"把 ...

  7. java中三种基本循环方式详解

    #博学谷IT学习技术支持# Java循环for,while和do-while 简述:如果对于同一种操作需要执行多次的话,就要使用到循环结构.它可以大大简化代码的书写量,让我们的开发更便捷. 例如:打印 ...

  8. C#中三种截屏方式总结

    昨天写自动化测试的CASE的时候,碰到一个疑难杂症,调用截图的函数去截取一个Popup窗口,但是总是把背景程序给截下来,Popup窗口就跟看不到一样.本来以为是同步的问题,也就是以为先截图再点击弹出P ...

  9. Java中三种交换值得方式

    方式一: 适用于任意数据类型 int i= 3 ,j=4; int temp = 0; temp = i; i = j; j = temp; 方式二:只适用于整型数据 int i = 3,j = 4; ...

最新文章

  1. epoll 的实现原理以及与poll,select 的对比
  2. Session Cookies Cache 的区别
  3. MVVM架构~knockoutjs系列之验证成功提示显示
  4. Fbpanel-轻巧的面板措施
  5. oracle的簇与簇表
  6. Hadoop平台K-Means聚类算法分布式实现+MapReduce通俗讲解
  7. IP通信基础 实验三
  8. pitr 原理_PostgreSQL基于时间点恢复(PITR)
  9. Bootstrap 进度条堆叠
  10. python做性能测试_Python做性能测试-1、Locust基础篇
  11. ADS20XX完全安装(任意盘)、卸载指南
  12. java try 性能损耗_Java上的try catch并不影响性能(转)
  13. 工作三年的前端开发20k简历标准
  14. 东北大学软件项目管理与过程改进复习提纲(2020)——第一章
  15. 贝尔机:带你领略编码的魅力
  16. Python-知识点Demo练习
  17. 世界各国面积排名国家国土面积 (万平方公里)
  18. Silverlight 框架
  19. 时代周刊-老牛上封面的那一期
  20. 优效文件助手-【深度】都2021年了,你还只会用文件夹管理电脑文件?

热门文章

  1. 异常 | 求你别再写满屏的try-catch了,用全局异常好吗?- 夹私货-行测
  2. 设计模式-单一职责原则
  3. Bootstrap带下拉的胶囊导航
  4. HTML autofocus
  5. python内建函数是什么意思_python内建函数是什么意思
  6. HDU2159 FATE(二维背包、带限制条件的背包问题)
  7. cloudera cdh5.13.0 vmware 快速安装
  8. Git - Pull Request工作流
  9. CentOS图形界面下如何安装Eclipse和使用maven
  10. 实现三联tab切换特效