一个编译单元中的静态初始化

Arkady

静态初始化以及描述的内容,在这里在这个网站,甚至在这里

到处都写到,如果存在带有相关静态变量的不同编译单元,则会出现问题。而且,如果静态变量存在于一个编译单元中,那应该没有问题:它们将按照其在文件中的位置顺序进行初始化。

但是我有这段代码:

template <typename T>
class A{
public:
    int _data;
    T _obj;
    A(int data) :_data(data){}
};

template <typename T>
class B{
public:
    const static B<T> nullObj;
    B(int data) :_a(new A<T>(data)){}
    A<T> *_a;
};

template <typename T>
class C{
public:
    const static C<T> nullObj;
    C() :_a(nullObj._a){}
    C(bool t) :_a(B<T>::nullObj._a){
        _a->_data++; //FAILS HERE!
    }
    A<T> *_a;
};

template <typename T>
const B<T> B<T>::nullObj(0);

template <typename T>
const C<T> C<T>::nullObj(false);

class _B{};
class  _A{ public: _A(){}; C<_B> g; };

int main(){
    return 0;
}

而且在进入main()函数之前,它在运行时失败,因为它会在初始化const C<T> C<T>::nullObj(false); 之前 尝试进行const B<T> B<T>::nullObj(0);初始化。尽管他们在一个文件中的位置。

为什么它尝试在第一个静态变量之前初始化第二个静态变量?C ++ Standart中是否存在用静态初始化序列描述实际情况的章节?

量子开发

C ++标准的14.7.1节[temp.inst]:

除非已明确实例化或显式实例化了类模板或成员模板的成员,否则在需要成员定义存在的上下文中引用专门化时,将隐式实例化成员的专门化。特别是,除非静态数据成员本身以要求静态数据成员的定义存在的方式使用,否则不会发生静态数据成员的初始化(以及任何相关的副作用)


C<T>在之前实例化B<T>,因此初始化的顺序定义明确,并且为:

1) const static C<T> nullObj;

2) const static B<T> nullObj;

由于C构造函数取消引用B<T>::nullObj._a,因此您具有未定义的行为。

解:

您必须B<_B>::nullObj以某种方式使用静态成员才能对其进行初始化,例如,如果这样做:

class _B{};
class _A{ public: _A() : b(B<_B>::nullObj) {}; B<_B> b; C<_B> g; };

然后B<_B>::nullObj确实在C构造函数需要它之前进行了初始化

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

在构造函数中初始化一个静态的final字段

同一个函数中的静态函数变量初始化顺序

调用另一个翻译单元的功能可能导致静态初始化顺序惨败

为什么我不能按顺序在一个文件中初始化两个静态类变量,而不能初始化三个?

在Swift中重新初始化一个懒惰的初始化变量

在python中初始化一个空的csv?

在C中初始化一个联合

在主线程中初始化一个变量

在C ++中初始化一个指针

在EmberJS中创建一个初始化脚本

Python初始化一个类中的列表

静态类中的异步延迟初始化无法编译

PHP-有没有办法初始化一个类并在一行中调用一个非静态方法?

将数据从一个屏幕传递到另一个屏幕时,只能在初始化程序中访问静态成员

用另一个初始化的静态变量

静态初始化字段以指向另一个字段

仅使用一个静态方法(没有构造函数)初始化类

从另一个类的静态方法初始化Spring bean?

显式实例化模板的静态成员和另一个静态变量的初始化顺序

用递增的数字初始化一个编译时常量大小的数组

未初始化的成员未被编译器捕获。这是一个错误吗?

有没有办法从不同类中的另一个const静态字段初始化const静态字段?

如何以静态方式使用另一个constexpr数组初始化一个数组

使用宏将一个工作簿中的单元格的值初始化到另一个工作簿

为什么一个静态变量的一个方法调用返回另一个静态变量保持为空初始化?

一个线程能否在另一个线程完成静态初始化(类加载)之前进入一个静态方法?

在另一个类中初始化一个指针

在 ASP .NET 中使用静态类初始化另一个静态类的成员

也许在Rust中取消初始化和初始化ZST / unhabbited /一个表示类型