一、C++类初始化普通成员变量
1、 有三个地方可以初始化普通成员变量:
(1)、声明处;
(2)、初始化列表处;
(3)、构造函数里。
2、 先后顺序:
(1)、声明处 > 初始化列表 > 构造函数。
(2)、举例:
class A
{
public:
A();
public:
int a = 1;
int b = 2;
int c = 3;
};
A::A() : a(4), b(5), c(6)
{
c = 7;
}
int main()
{
A a;
std::cout << "a = " << a.a << "; b = " << a.b << "; c = " << a.c << std::endl;
system("pause");
return 0;
}
运行结果:
a = 4; b = 5; c = 7
3、 在声明处,初始化普通成员变量的顺序: 先声明先初始化,后声明后初始化。
(1)、本质上,普通成员变量的初始化顺序和变量在内存中次序有关,而变量在内存中的排列顺序由变量的定义次序决定。
(2)、 举例:
class A
{
public:
A();
public:
int a = 1;
int b = c + 2;
int c = 3;
};
A::A()
{
}
int main()
{
A a;
std::cout << "a = " << a.a << "; b = " << a.b << "; c = " << a.c << std::endl;
system("pause");
return 0;
}
运行结果:
a = 1; b = -858993458; c = 3
b为乱码,因为初始化顺序为a > b > c, 初始化b时,c还没有被初始化。
4、 在初始化列表处,初始化列表只指定普通成员变量的值,不指定变量初始化的顺序,变量初始化顺序依旧由声明顺序决定。
(1)、 举例:
class A
{
public:
A();
public:
int a;
int b;
int c;
};
A::A() : b(1), a(b), c(b)
{
}
int main()
{
A a;
std::cout << "a = " << a.a << "; b = " << a.b << "; c = " << a.c << std::endl;
system("pause");
return 0;
}
运行结果:
a = -858993460; b = 1; c = 1
a为乱码,因为初始化顺序为a > b > c, 初始化a时, b还没有被初始化。
5、 在构造函数里,普通成员变量初始化的顺序和初始化语句先后顺序有关。
(1)、举例:
class A
{
public:
A();
public:
int a;
int b;
int c;
};
A::A()
{
a = 1;
c = a + 1;
b = c + 1;
}
int main()
{
A a;
std::cout << "a = " << a.a << "; b = " << a.b << "; c = " << a.c << std::endl;
system("pause");
return 0;
}
运行结果:
a = 1; b = 3; c = 2
初始化顺序为a > c > b。
二、注意:
1、 普通成员变量,三处初始化地方选择其一即可,只是注意初始化顺序问题,防止初始化顺序导致程序出错。
2、 const成员变量,只能在声明处或初始化列表处初始化值,不能在构造函数里初始化值。
(1)、举例:以下代码编译失败。
class A
{
public:
A();
public:
const int a;
};
A::A()
{
a = 10;
}
3、 静态成员变量,必须在类外初始化,且初始化顺序先于普通成员变量和const成员变量。
(1)、举例:
错误初始化:
class A
{
public:
A();
public:
static int a = 10;
};
A::A()
{
}
正确初始化:
class A
{
public:
A();
public:
static int a;
};
A::A()
{
}
int A::a = 10; //注意: "static int A::a = 10;"也是编译失败。
三、总结变量初始化顺序:
1、 基类的静态成员变量;
2、 派生类的静态成员变量;
3、 基类的普通成员变量和const成员变量;
4、 派生类的普通成员变量和const成员变量。