为了账号安全,请及时绑定邮箱和手机立即绑定

什么时候初始化静态C ++类成员?

什么时候初始化静态C ++类成员?

C++
慕盖茨4494581 2019-08-19 11:11:35
什么时候初始化静态C ++类成员?似乎没有简单的答案,但是有什么假设可以安全地进行静态类字段的访问吗?编辑:唯一安全的假设似乎是所有静态都在程序开始之前初始化(调用main)。那么,只要我不参考其他静态初始化代码中的静态,我就没有什么可担心的了?
查看完整描述

3 回答

?
慕工程0101907

TA贡献1887条经验 获得超5个赞

该标准保证两件事 - 在同一翻译单元中定义的对象(通常表示.cpp文件)按其定义(而不是声明)的顺序初始化:

3.6.2

具有静态存储持续时间(basic.stc.static)的对象的存储应在任何其他初始化发生之前进行零初始化(dcl.init)。使用常量表达式进行零初始化和初始化统称为静态初始化; 所有其他初始化是动态初始化。具有使用常量表达式(expr.const)初始化的静态存储持续时间的POD类型(basic.types)的对象应在任何动态初始化发生之前初始化。在同一翻译单元的命名空间范围内定义并动态初始化的静态存储持续时间的对象应按其定义出现在翻译单元中的顺序进行初始化。

另一个有保证的事情是,在使用来自此翻译单元的任何对象或函数之前,将从翻译单元初始化静态对象:

无论是否在main的第一个语句之前完成命名空间作用域对象的动态初始化(dcl.init,class.static,class.ctor,class.expl.init),它都是实现定义的。如果初始化延迟到main的第一个语句之后的某个时间点,则它应该在第一次使用与要初始化的对象相同的转换单元中定义的任何函数或对象之前发生。

我保证没有其他任何东西(特别是在不同翻译单元中定义的对象的初始化顺序是实现定义的)。


查看完整回答
反对 回复 2019-08-19
?
函数式编程

TA贡献1807条经验 获得超9个赞

它们在程序开始之前(即在main输入之前)初始化。

当单个CPP文件中存在两个或多个(静态数据的)定义时,它们将按照在文件中定义它们的顺序进行初始化(文件中先前/后面定义的那个在下一个之前初始化)一个是)。

当在多个CPP文件中存在两个或多个(静态数据的)定义时,处理CPP文件的顺序是未定义/特定于实现的。如果全局变量的构造函数(在程序启动之前调用)引用另一个可能尚未构造的CPP文件中定义的全局变量,则会出现此问题。但是,Meyers的Effective C ++(标题为确保全局对象在使用前已初始化)的 47项确实描述了一种解决方法......

  • 在头文件中定义一个静态变量(它是静态的,所以你可以有多个实例而不需要链接器抱怨)

  • 让该变量的构造函数调用您需要的任何东西(特别是构造在头文件中声明的全局单例)

...它说的是一种可以在某些系统头文件中使用的技术,例如确保cin在静态变量的构造函数使用它之前初始化全局变量。


查看完整回答
反对 回复 2019-08-19
?
心有法竹

TA贡献1866条经验 获得超5个赞

您在编辑中的最终结论是正确的。但问题是班级自己。更容易说我的代码将具有不引用其他全局数据/类静态成员的类静态成员,但是一旦采用这种方法,事情很快就会出错。我发现在实践中有一种方法是不使用类静态数据成员而是使用类静态包装器方法。然后,这些方法可以将静态对象保存在自身内。例如

TypeX* Class2::getClass1Instance(){
    static TypeX obj1;
    return &obj1;}

注意:早先的答案是:

另一个有保证的事情是,在使用来自此翻译单元的任何对象或函数之前,将完成从翻译单元初始化静态对象

这不完全正确,这里错误地推断出标准。如果在输入main之前调用翻译单元中的函数,则这可能不成立。


查看完整回答
反对 回复 2019-08-19
  • 3 回答
  • 0 关注
  • 948 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信