我想知道为什么有时我在单独的.h文件中定义的全局const在我需要的时候没有正确初始化。一些测试导致我无法理解的情况。我不知道如何解释它,所以这是代码:
#include <iostream>
#include "class.h"
using namespace std;
A a;
B b;
int main(int argc, char* argv[]){
A aa;
B bb;
cout<<a.a<<" "<<aa.a<<endl;
cout<<b.b<<" "<<bb.b<<endl;
return 0;
}
#ifndef CLASS_H
#define CLASS_H
#include "const.h"
class A {
public:
A();
float a;
};
class B {
public:
B():b(CONST){}
float b;
};
#endif
#include "class.h"
A::A()
: a(CONST){}
#ifndef CONST_H
#define CONST_H
#include <limits>
using namespace std;
const float CONST = numeric_limits<float>::has_infinity ?
-numeric_limits<float>::infinity() :
-numeric_limits<float>::max();
#endif
运行上面的代码后,我得到:
0 -1。#INF
-1。#INF -1。#INF
实际上我想得到4次'-1。#INF'。 为什么会这样?如果CONST是'1'而不是上面的公式,它将完美地工作。
我可以通过制作静态getConst()方法来“修复”它:
static float getConst(){
static const float CONST = numeric_limits<float>::has_infinity ?
-numeric_limits<float>::infinity() :
-numeric_limits<float>::max();
return CONST;}
但它并没有“感觉”正确。另一方面,我只需要上面的两个......但也许还有其他方法?
而且,最重要的是,为什么B级得到“正确”的CONST和A级呢?
答案 0 :(得分:3)
不同翻译单元中全局对象的初始化顺序不保证。
请查看此stackoverflow问题:Static variables initialisation order
答案 1 :(得分:1)
常量对象具有内部链接,因此您在每个包含CONST
的编译单元中获得const.h
的单独副本。在这种情况下,您将在main.cpp
中获得一个,在class.cpp
中获得一个。您还在main.cpp
中拥有两个全局对象。
C ++没有定义初始化不同编译单元中的全局对象的顺序。 A
的构造函数是从main.cpp
调用的,需要来自class.cpp
的全局常量,该常量可能尚未初始化。在您的特定情况下,它没有,所以您得到的值不正确。 B
的构造函数是内联的,因此它使用来自main.cpp
的全局常量,该常量已经初始化,因为它是在同一个编译单元中先前定义的。
通过使常量成为函数静态对象,现在可以保证在首次调用该函数时对其进行初始化。
答案 2 :(得分:0)
我没有看到const.h
的内容,所以我只能猜出CONST
是什么(宏?)。
除此之外,在您的代码示例中,成员变量A::a
未初始化。因此,它可以有任何价值 - 它是未初始化的。
答案 3 :(得分:0)
如果我正确理解你的问题,那么我认为问题是因为没有定义任何全局对象的初始化顺序。