关于全局、static对象/变量的初始化问题
2007-05-05 11:01
453 查看
关于全局、static对象/变量的初始化问题
1. 全局变量、static变量的初始化时机:main()函数执行之前(或者说main中第一个用户语句执行之前)。
2. 初始化顺序。
1)全局对象、外部static对象
a)同一编译单元(同一源文件)中,按照对象/变量的定义顺序初始化。
b)不同编译单元,C++标准未保证初始化先后顺序,只保证都在main()之前初始化完成。
2)函数内部local static变量,在该函数调用过程中第一次遇到该static变量时初始化。
基于以上观点,大师们建议少用全局变量,全局变量之间要消除依赖关系——特别是初始化依赖关系!
全局变量的使用可以参考 Scott Meyers 在《More Effective C++》中M34所说的,模拟Singleton模式,通过函数内部的local static变量来代替全局变量。
写个示例程序验证下这些变量的初始化,中间的注释部分就作为上面结论的一些补充吧。
[align=center][/align]
class CA
{
public:
class CInner
{
public:
CInner()
{
cout << "constructor of inner class CInner." << endl << endl;
}
};
public:
CA()
{
cout << "Constructor of CA." << endl;
cout << " m_i1 = " << m_i1
<< ", m_i2 = " << m_i2
<< ", m_i3 = " << m_i3
<< ", m_i4 = " << m_i4 << endl << endl;
}
static void Func1()
{
cout << " In function Func1()." << endl;
static CInner myInner1;
}
static void Func2()
{
cout << " In function Func2(), m_i1 = " << m_i1 << endl;
if(m_i1 < 10)
{
cout << "m_i1 < 10 and Constructor of CInner won't be called!" << endl << endl;
return;
}
static CInner myInner2;
}
public:
static int m_i1;
static int m_i2;
static const int m_i3;
static int m_i4;
};
/* 不同模块的全局、static变量/对象初始化顺序不确定;
* 同一个编译模块按定义顺序初始化。
* 但有一点相同,就是它们均在编译期已分配好内存。
* 对于诸如基本数据类型,编译期能确定其值的,编译器就直接将值写入分配的空间,如“CA::m_i1=3"。
* 对于编译期不能确定值的,要等到运行时main函数之前初始化,如theCA、CA::m_i2。
* 但若static的初始化表达式均为const或字面常量等确定的值,则亦能在编译期确定值,如m_i4。
*/
int CA::m_i1 = 1;
CA theCA;
const int CA::m_i3 = 3;
int CA::m_i2 = CA::m_i1 + 1;
int CA::m_i4 = CA::m_i3 + 1;
int main(int argc, _TCHAR* argv[])
{
CA::Func1();
CA::Func2();
cout << "After CA::m_i1 increased by 11 :" << endl;
CA::m_i1 += 11;
CA::Func2();
return 0;
}
[align=center][/align]
以上程序运行结果为:
Constructor of CA.
m_i1 = 1, m_i2 = 0, m_i3 = 3, m_i4 = 4
In function Func1().
constructor of inner class CInner
In function Func2(), m_i1 = 1
m_i1 < 10 and Constructor of CInner won't be called!
After CA::m_i1 increased by 11 :
In function Func2(), m_i1 = 12
constructor of inner class CInner.
1. 全局变量、static变量的初始化时机:main()函数执行之前(或者说main中第一个用户语句执行之前)。
2. 初始化顺序。
1)全局对象、外部static对象
a)同一编译单元(同一源文件)中,按照对象/变量的定义顺序初始化。
b)不同编译单元,C++标准未保证初始化先后顺序,只保证都在main()之前初始化完成。
2)函数内部local static变量,在该函数调用过程中第一次遇到该static变量时初始化。
基于以上观点,大师们建议少用全局变量,全局变量之间要消除依赖关系——特别是初始化依赖关系!
全局变量的使用可以参考 Scott Meyers 在《More Effective C++》中M34所说的,模拟Singleton模式,通过函数内部的local static变量来代替全局变量。
写个示例程序验证下这些变量的初始化,中间的注释部分就作为上面结论的一些补充吧。
[align=center][/align]
class CA
{
public:
class CInner
{
public:
CInner()
{
cout << "constructor of inner class CInner." << endl << endl;
}
};
public:
CA()
{
cout << "Constructor of CA." << endl;
cout << " m_i1 = " << m_i1
<< ", m_i2 = " << m_i2
<< ", m_i3 = " << m_i3
<< ", m_i4 = " << m_i4 << endl << endl;
}
static void Func1()
{
cout << " In function Func1()." << endl;
static CInner myInner1;
}
static void Func2()
{
cout << " In function Func2(), m_i1 = " << m_i1 << endl;
if(m_i1 < 10)
{
cout << "m_i1 < 10 and Constructor of CInner won't be called!" << endl << endl;
return;
}
static CInner myInner2;
}
public:
static int m_i1;
static int m_i2;
static const int m_i3;
static int m_i4;
};
/* 不同模块的全局、static变量/对象初始化顺序不确定;
* 同一个编译模块按定义顺序初始化。
* 但有一点相同,就是它们均在编译期已分配好内存。
* 对于诸如基本数据类型,编译期能确定其值的,编译器就直接将值写入分配的空间,如“CA::m_i1=3"。
* 对于编译期不能确定值的,要等到运行时main函数之前初始化,如theCA、CA::m_i2。
* 但若static的初始化表达式均为const或字面常量等确定的值,则亦能在编译期确定值,如m_i4。
*/
int CA::m_i1 = 1;
CA theCA;
const int CA::m_i3 = 3;
int CA::m_i2 = CA::m_i1 + 1;
int CA::m_i4 = CA::m_i3 + 1;
int main(int argc, _TCHAR* argv[])
{
CA::Func1();
CA::Func2();
cout << "After CA::m_i1 increased by 11 :" << endl;
CA::m_i1 += 11;
CA::Func2();
return 0;
}
[align=center][/align]
以上程序运行结果为:
Constructor of CA.
m_i1 = 1, m_i2 = 0, m_i3 = 3, m_i4 = 4
In function Func1().
constructor of inner class CInner
In function Func2(), m_i1 = 1
m_i1 < 10 and Constructor of CInner won't be called!
After CA::m_i1 increased by 11 :
In function Func2(), m_i1 = 12
constructor of inner class CInner.
相关文章推荐
- C/C++之全局、static对象/变量的初始化问题
- 关于全局变量的初始化问题与野指针
- 在Java中关于静态变量和全局变量什么时候初始化的问题
- 7 面向对象(成员变量和局部变量的区别,类作为形式参数的问题,匿名对象,封装,private关键字,this关键字,构造方法,类的初始化过程,static关键字)
- 关于C未初始化全局变量的连接问题
- 关于C/C++中全局变量的初始化问题的深入思考
- [笔试题 9][c/c++]关于成员变量,对象成员的初始化问题
- 关于对于c语言全局变量初始化问题
- 关于全局变量初始化与赋值问题的思考
- 全局变量和局部变量初始化问题
- 关于Javascript循环体变量声明与初始化的效率问题
- UserControl 中包含封装了集合对象的属性被设计器自动初始化所引起的错误!也有关于List的问题
- C/C++中全局变量,静态局部变量,局部变量的初始化问题
- 关于JAVA中变量的初始化及类属性的默认值问题
- C语言学习4: 函数返回值与传入参数,关于函数值传递和类型隐性转换,变量不同的作用域,static变量,多文件编译例如两个C文件,显示函数调用语句跳转,递归,斐波那契数列,多文件编译相同变量的问题。
- 关于全局变量和局部变量的调用问题
- PHP中关于在函数内引用全局变量的问题
- 构造函数的职责 -- 关于全局变量的构造函数里执行太多复杂操作导致的问题
- 关于java中变量的初始化的问题
- 关于JavaScript的全局变量的问题