C++学习之成员变量的初始化顺序


这篇文章是有关C++成员变量初始化顺序的学习内容。

我现在是研一,最近研二的学长学姐们都在准备找实习,各种面试笔试,工作不好找,形势好严峻。所以听从学长的建议从现在开始积累编程语言(C++、Python)、算法、数据结构方面的基础知识,为今后面试找工作做好准备。在读剑指offer书时遇到成员变量初始化顺序这种问题,打算查资料深入学习下。

首先是下面的测试代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
#include <iostream>
using namespace std;

class A
{
private:
int n1;
int n2;

public:
//成员变量初始化方式一:构造函数初始化列表初始化
A():n2(0),n1(n2+2){}

//成员变量初始化方式二:构造函数内初始化
//A(){
// n2 = 0;
// n1 = n2 + 2;
//}
void Print(){
cout << "n1:" << n1 << ", n2: " << n2 <<endl;
}
};

int main(int argc, char **argv) {
A a;
a.Print();
return 1;
}

方式一:类的成员变量通过构造函数初始化列表初始化时,这段代码的输出结果:n1:32766, n2:0,当然多次执行时,n1的值并不相同。

方式二:在构造函数内部初始化成员变量时,输出结果:n1:2, n2:0

分析

1、成员变量在使用初始化列表初始化时,与构造函数中初始化成员列表的顺序无关,只与定义成员变量的顺序有关。因为成员变量的初始化次序是由变量在内存中的次序决定的,而内存中的排列顺序早在编译期就根据变量的定义次序决定了。这点在EffectiveC++中有详细介绍。

2、如果不使用初始化列表初始化,在构造函数内初始化时,此时与成员变量在构造函数中的位置有关。

3、注意:类的成员变量在定义时,不能初始化。因为此时类并没有进行实例化(创建对象),因此并没有分配内存。

4、注意:类中const成员常量必须在构造函数初始化列表中初始化。

5、注意:类中static成员变量,必须在类外初始化。

6、静态变量进行初始化顺序是基类的静态变量先初始化,然后是其派生类,直到所有的静态变量都被初始化。这里需要注意全局变量和静态变量的初始化是不分次序的。这也不难理解,其实静态变量和全局变量都被放在公共内存区。可以把静态变量理解为带有”作用域“的全局变量。在一切初始化工作结束后,main函数会被调用,如果某个类的构造函数被执行,那么首先基类的成员变量会被初始化。

总结

  1. 类的成员变量的初始化

    • 非static非const成员变量,一般在构造函数中进行初始化
    • static成员变量,必须在类的外面进行初始化(在类的实现时,在类的外部进行初始化)
    • const成员变量,必须在类的构造函数的初始化列表中初始化
    • static const成员变量,可以在类的内部声明时初始化
  2. 类的成员变量初始化顺序

    • 基类的静态变量或全局变量
    • 派生类的静态变量或全局变量
    • 基类的成员变量
    • 派生类的成员变量
  3. 必须在构造函数的初始化列表中的情况

    • 类的const常量
    • 类的引用类型成员
    • 没有默认构造函数的类类型成员
    • 如果类存在继承关系,派生类必须在其初始化列表中调用基类的构造函数

本文标题:C++学习之成员变量的初始化顺序

文章作者:阿翔

发布时间:2018年03月28日 - 11:03

最后更新:2019年05月28日 - 21:05

原始链接:http://ttshun.com/2018/03/28/C++学习之成员变量的初始化顺序/

许可协议: 署名-非商业性使用-禁止演绎 4.0 国际 转载请保留原文链接及作者。

点击给我一些鼓励叭!
-------------本文结束感谢您的阅读-------------
0%