引子:我们知道,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. Linux学习_菜鸟教程_3

    我是在UBANTO上运行Linux的,开机启动时按下shift或者Esc都不能进入到grub,没有百度到可靠的教程. 暂时先这样吧.免得我把系统搞坏了,先学点实用的知识~~ Next Chapter

  2. vue兄弟组件传值——事件总线

    1.创建一个js文件,例如msg.js,放到合适位置,例如components中,或者其他位置也行.然后在兄弟两个组件中分别引入msg.js文件 msg.js: import Vue from 'vu ...

  3. Java ArrayList类的简单介绍

    ArrayList类的说明: ArrayList类是List接口的实现类,java.util.ArrayList集合数据存储的结构是数组结构. 特点: 元素增删慢,查找快.(由于日常开发中使用最多的功 ...

  4. 重拾c++第二天(4):复合类型

    1.定义:种类 数组名[元素个数] = {元素1,...,元素n} ,或者直接赋值:数组名[元素位置] = 值; 2.部分初始化,其他全为0,可以就定义一个0,这样得到0数组(或者就一个{},别的啥也 ...

  5. linux入门系列7--管道符、重定向、环境变量

    前面文章我们学习了linux基础命令,如果将不同命令组合使用则可以成倍提高工作效率.本文将学习重定向.管道符.通配符.转义符.以及重要的环境变量相关知识,为后面的shell编程打下基础. 一.IO重定 ...

  6. OAuth2.0的那点荒唐小秘密 -几个简单概念和原理

    OAuth2.0这个名词你是否在项目中时常听到呢?是否觉得好像懂,又好像不太懂呢? 最近一直想写篇关于OAuth2.0的东西,记录下我的学习与感悟,然各种理由的拖延,直到今日才静下心来写下这篇博客.当 ...

  7. 代码审计之CVE-2017-6920 Drupal远程代码执行漏洞学习

     1.背景介绍: CVE-2017-6920是Drupal Core的YAML解析器处理不当所导致的一个远程代码执行漏洞,影响8.x的Drupal Core. Drupal介绍:Drupal 是一个由 ...

  8. 「4.0」一个人开发一个App,小程序从0到1,布局

    一提到布局这个词,我总是索索发抖,不是因为天冷,而是因为布局的目标实在太宏大.古代想雄霸天下的王,就喜欢布局这个,布局那个,结果硬生生把自己的国家给布局没了.至于是哪个君王,我倒可以非常认真,非常坦诚 ...

  9. 【python系统学习07】一张图看懂字典并学会操作

    点击跳转 - 原文地址 数据类型 - 字典(dict) 目录: 一张图get字典 字典是什么 js的对象 字典长啥样 语法伪代码 示例demo 语法成像 字典怎么用 字典长度获取--len函数 提取字 ...

  10. kuangbin专题专题十一 网络流 POJ 3436 ACM Computer Factory

    题目链接:https://vjudge.net/problem/POJ-3436 Sample input 1 3 4 15 0 0 0 0 1 0 10 0 0 0 0 1 1 30 0 1 2 1 ...