引子:我们知道,C++中类成员变量的初始化顺序与其在类中的声明顺序是有关的。

先看代码:

 class TestClass1
{
public:
TestClass1() {
cout << "TestClass1()" << endl;
}
TestClass1(const TestClass1&) { cout << "TestClass1(const TestClass1&)" << endl; }
TestClass1& operator=(const TestClass1&) { cout << "TestClas1s& operator=(const TestClass1&)" << endl; return *this; }
~TestClass1() {
cout << "~TestClass1()" << endl;
}
}; class TestClass2
{
public:
TestClass2() {
cout << "TestClass2()" << endl;
}
TestClass2(const TestClass2&) { cout << "TestClass2(const TestClass2&)" << endl; }
TestClass2& operator=(const TestClass2&) { cout << "TestClass2& operator=(const TestClass2&)" << endl; return *this; }
~TestClass2() {
cout << "~TestClass2()" << endl;
}
}; class Test
{
public:
Test() = default;
Test(TestClass1& tc1, TestClass2& tc2) :m_tc2(tc2), m_tc1(tc1){}
private:
TestClass1 m_tc1;
TestClass2 m_tc2;
};
 int main()
{
Test t;
}

程序结果为:

现象:先调用TestClass1的构造函数,再调用TestClass2的构造函数。

原因:在类Test中,m_tc1变量声明在m_tc2变量之前,故m_tc1在m_tc2之前初始化。

问题:在列表初始化的构造函数中,将m_tc2放在m_tc1之前,是否可以让m_tc2在m_tc1之前初始化?

代码设计

int main()
{
TestClass1 tc1;
TestClass2 tc2;
cout << "/**************************************************************************************/" << endl;
Test t(tc1, tc2);
}

运行结果为:

可以看到:仍然是TestClass1的构造函数先被调用,TestClass2的构造函数接着被调用。

结论:C++中类成员变量的初始化顺序与其在类中的声明顺序是有关的,而与其在初始化列表中的顺序无关。

再举一个例子:

然后我将代码写成这样:

 class Test
{
public:
Test() = default;
Test(TestClass1& tc1, TestClass2& tc2):m_tc2(tc2){}
private:
TestClass1 m_tc1;
TestClass2 m_tc2;
}; int main()
{
TestClass1 tc1;
TestClass2 tc2;
cout << "/**************************************************************************************/" << endl;
Test t(tc1, tc2);
}

注意与之前代码的差别:我们在初始化列表中只初始化了m_tc2,没有动m_tc1。

运行结果:

结果分析:在初始化Test的对象t时,由于m_tc1的声明顺序在m_tc2的声明顺序之前,所以t会想要先初始化m_tc1,但是它在初始化列表中没有找到初始化m_tc1的内容,于是它只好调用m_tc1的默认构造函数了,完成m_tc1的初始化后,再根据初始化列表中的内容初始化m_tc2。

C++中类成员变量在初始化列表中的初始化顺序的更多相关文章

  1. C++解析(12):初始化列表与对象构造顺序、析构顺序

    0.目录 1.类成员的初始化 2.类中的const成员 3.对象的构造顺序 3.1 局部对象的构造顺序 3.2 堆对象的构造顺序 3.3 全局对象的构造顺序 4.对象的析构顺序 5.小结 1.类成员的 ...

  2. Effective C++学习笔记:初始化列表中成员列出的顺序和它们在类中声明的顺序相同

    类成员的默认初始化顺序是按照声明顺序进行, 如果使用初始化列表初始化成员变量, 则必须按照成员变量的声明顺序进行; 否则, 在变量之间交替赋值时, 会产生, 未初始化的变量去赋值其他变量; 同时GCC ...

  3. C++中的初始化列表中可以对那些变量或对象进行初始化

    构造函数与其函数体之间可以添加初始化列表,能对某些对象进行初始化.格式为 类名() : 变量1(参数1),变量2(参数2) { } 1.     父类的对象的构造必须在初始化列表中,如: 子类名(): ...

  4. 【c++】构造函数初始化列表中成员初始化的次序性

    上代码 #include <iostream> using namespace std; class A { public: A(int v): j(v + 2), i(j) {} voi ...

  5. Java中类成员变量初始化顺序

    一. 定义处默认初始化vs构造函数中初始化 java中类成员变量支持在声明处初始化,也可以在构造函数中初始化,那么这两者有什么区别呢?看下面例子 public class FieldsInit { p ...

  6. 正确理解Widget::Widget(QWidget *parent) :QWidget(parent)这句话(初始化列表中无法直接初始化基类的数据成员,所以你需要在列表中指定基类的构造函数)

    最近有点忙,先发一篇我公众号的文章,以下是原文. /********原文********/ 最近很多学习Qt的小伙伴在我的微信公众号私信我,该如何理解下面段代码的第二行QWidget(parent) ...

  7. 【c++】必须在类初始化列表中初始化的几种情况

    转自:http://www.cnblogs.com/kaituorensheng/p/3477630.html 1. 类成员为const类型 2. 类成员为引用类型 #include <iost ...

  8. java中成员变量、代码块、构造函数运行顺序

    1.java虚拟机执行程序,首先须要装载类,安装现装载父类,初始化父类的静态代码块和静态成员变量 再load子类. 初始化子类静态代码块和成员变量 2.load完成父类与子类后,从main函数入口运行 ...

  9. Python3基础 list in/not in 判断一个变量是否在列表中存在

             Python : 3.7.0          OS : Ubuntu 18.04.1 LTS         IDE : PyCharm 2018.2.4       Conda ...

随机推荐

  1. 微信小程序之豆瓣电影

    此文是学习小程序第二天做出的一个小demo,调用了豆瓣电影的api,但是需要填上自己appId,现在项目的 目录如下图: 效果图如下: 在这个demo里面,我更改了小程序的navigationBar, ...

  2. 【Java并发基础】并发编程领域的三个问题:分工、同步和互斥

    前言 可以将Java并发编程抽象为三个核心问题:分工.同步和互斥. 这三个问题的产生源自对性能的需求.最初时,为提高计算机的效率,当IO在等待时不让CPU空闲,于是就出现了分时操作系统也就出现了并发. ...

  3. 悄摸直播 —— JavaCV实现本机摄像头画面远程直播

    目录 前言 需要的jar包和依赖 需要实现的模块(附带源码教程) 项目效果展示 前言 最近想用Java实现一个类似于远程直播的功能 像这样:(功能示意图) 需要的jar包和依赖 Maven依赖: &l ...

  4. CF825G Tree Queries

    [题意] 一棵树有 n个节点,初始均为白色,有两种操作: 1. 1 x 代表把结点 x 设置为黑色 2. 2 x 代表查询 x 到树上任意一个黑色结点的简单路径上的编号最小的结点的编号 输入 t 和 ...

  5. ubuntu频繁死机--独立显卡问题

    问题:笔记本安装ubuntu时以及装好后有时会出现花屏.死机的问题,系统报错 *ERROR* UVD not responding, trying to reset the VCPU!!! *ERRO ...

  6. python的list()函数

    list()函数将其它序列转换为 列表 (就是js的数组). 该函数不会改变   其它序列 效果图一: 代码一: # 定义一个元组序列 tuple_one = (123,','abc') print( ...

  7. MADP(移动应用开发平台)推动企业数字化转型

    移动互联网时代,企业对于移动应用程序的需求呈现爆炸式增长,移动解决方案供应商一直致力于寻找解决方案帮助企业完成这些移动集成需求,MADP(移动应用开发平台)因此产生,MADP允许提供一种解决方案,可以 ...

  8. Centos7 搭建Grafana+Jmeter+Influxdb 性能实时监控平台

    未完,待更新 背景 日常工作中,经常会用到Jmeter去压测,毕竟LR还要钱(@¥&*...),而最常用的接口压力测试,我们都是通过聚合报告去查看压测结果的,然鹅聚合报告的真的是丑到家了,作为 ...

  9. DOCKER学习_017:Docker-Compose介绍

    dockers三驾马车 Docker Machine Docker Swarm Docker Compose 一 Docker Compose介绍 Docker Compose是一个定义和运行多容器应 ...

  10. 开始使用Manjaro

    Manjaro是什么? 一个基于Arch系列,开源的linux发行版 Mnajrao官网了解更多,这里不做更多阐述内容 为什么使用Manjaro 第一点,为了方便自己隔离腾讯网游 第二点,更方便的学习 ...