C++类成员变量初始化顺序问题

时间:2021-10-02 06:15:42

今天在看剑指offer这本书时,看待一个简单的举例,说应聘C++岗位的不知道成员变量初始化顺序!我很惊讶,因为我也不知道,所以就看上网查了一下,看到了一个博客()以及其中的内容,现在将我的学习过程分享出来!

首先看一下代码:

#include <iostream>
using namespace std;

class A
{
public:
A()
:n2(0),
n1(n2 + 2)
{}

//~A();

void print()
{
cout << "n1:" << n1 << " , n2:" << n2 << endl;
}

private:
int n1;
int n2;
};

//A::~A()
//{
//}

int main()
{
A a;
a.print();
system("pause");
return 0;
}
大家预测一下结果,在没运行的时候,我想大多数不懂初始化成员列表的顺序的人都会和我一样认为输出的是:n1:2  ,  n2:0 

然而运行之后,我的电脑运行结果如下

C++类成员变量初始化顺序问题

看来我们错了,我查询了一下知识点,得到的结果是:

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

现在我们试试用构造函数进行测试,代码如下:

#include <iostream>
using namespace std;

class A
{
public:
//A()
//:n2(0),
//n1(n2 + 2)
//{}

A()
{
n2 = 0;
n1 = n2 + 2;
}

//~A();

void print()
{
cout << "n1:" << n1 << " , n2:" << n2 << endl;
}

private:
int n1;
int n2;
};

//A::~A()
//{
//}

int main()
{
A a;
a.print();
system("pause");
return 0;
}
结果如下:

C++类成员变量初始化顺序问题

这个结果又表明:

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

接下来我又测试了const 成员变量和static成员变量,

当const成员变量在构造函数中初始化时,代码如下:

#include <iostream>
using namespace std;

class A
{
public:
//A()
//:n2(0),
//n1(n2 + 2)
//{}

A()
{
n2 = 0;
n1 = n2 + 2;
n3 = 4;
n4 = 5;
}

//~A();

void print()
{
cout << "n1:" << n1 << " , n2:" << n2 << "n3:" << n3 << " , n4:" << n4 << endl;
}

private:
int n1;
int n2;
const int n3;
static int n4;
};

//A::~A()
//{
//}

int main()
{
A a;
a.print();
system("pause");
return 0;
}
有错误,运行时报告的错误列表如下:

C++类成员变量初始化顺序问题 将在构造函数中初始化变成在初始化列表中初始化,代码如下:

A()
: n2(0),
n1(n2 + 2),
n3(4),
n4(5)
{}
然而结果又有错误,错误如下:

C++类成员变量初始化顺序问题 上边两次试验说明:

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

类中static成员变量,不能在类内初始化。

编辑代码测试,代码如下:

#include <iostream>
using namespace std;

class A
{
public:
A()
<span style="white-space:pre"></span>:n3(4)
{
n2 = 0;
n1 = n2 + 2;
}

void print()
{
cout << "n1:" << n1 << " , n2:" << n2 << " , n3:" << n3 << endl;
}
int Getn4()
{
n4 += 5;
return n4;
}
public:
static int n4;
private:
int n1;
int n2;
const int n3;

};
int A::n4 = 3; <span style="white-space:pre"></span>//必须这样初始化

int main()
{
A a;
cout << "A:n4: " << A::n4 << endl;
A::n4 = 7; <span style="white-space:pre"></span>//必须这样赋值或者通过成员函数
a.print();
cout << "A:n4: " << A::n4 << endl;
a.Getn4();<span style="white-space:pre"></span>
cout << "A:n4: " << A::n4 << endl;
system("pause");
return 0;
}
结果如下:

C++类成员变量初始化顺序问题 介绍一下静态变量:

    静态成员是类所有的对象的共享的成员,而不是某个对象的成员。它在对象中不占用存储空间,这个属性为整个类所共有,不属于任何一个具体对象。所以静态成员不能在类的内部初始化,比如声明一个学生类,其中一个成员为学生总数,则这个变量就应当声明为静态变量,应该根据实际需求来设置成员变量。

下面列出总结:

1.成员变量在使用初始化列表初始化时,与构造函数中初始化成员列表的顺序无关,只与定义成员变量的顺序有关。

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

3.类中const成员常量必须在构造函数初始化列表中初始化。

4.类中static成员变量,只能在类内外初始化(同一类的所有实例共享静态成员变量)。

下面是C++类成员变量初始化顺序:

  • 1) 基类的静态变量或全局变量
  • 2) 派生类的静态变量或全局变量
  • 3) 基类成员变量
  • 4) 派生类的成员变量

谢谢各位批评指正!!!