[英]Global const initializing and difference between constructor in .h or .cpp file
I was wondering why sometimes my global const defined in seperate .h file isn't properly initialized when I need it. 我想知道为什么有时在单独的.h文件中定义的全局const在需要时没有正确初始化。 Some tests lead me to situation that I can't understand.
一些测试将我引向我无法理解的情况。 I don't know how to explain it, so here's the code:
我不知道如何解释它,所以这是代码:
#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
After running above code I get: 运行上面的代码后,我得到:
0 -1.#INF
0 -1。#INF
-1.#INF -1.#INF-1。#INF -1。#INF
when actually I would like to get 4 times '-1.#INF'. 实际上我想得到4倍的“ -1。#INF”。 Why does it happen this way?
为什么会这样发生? If CONST would be '1' instead of above formula, it would work perfectly.
如果CONST为'1'而不是上面的公式,它将很好地工作。
I can "fix" it by making static getConst() method: 我可以通过制作静态getConst()方法来“修复”它:
static float getConst(){
static const float CONST = numeric_limits<float>::has_infinity ?
-numeric_limits<float>::infinity() :
-numeric_limits<float>::max();
return CONST;}
but it just doesn't "feel" right. 但这只是“感觉”不对。 On other hand I just need two of those above... But maybe there's some other way?
另一方面,我只需要以上两个...但是也许还有其他方法吗?
And, most importantly, why class B gets "right" CONST and class A don't? 而且,最重要的是,为什么B类获得“正确的” CONST,而A类却没有?
The order of initialization of global object in different translation unit is not guarantee. 不保证在不同翻译单元中全局对象的初始化顺序。
Please have a look at this stackoverflow question: Static variables initialisation order 请看一下这个stackoverflow问题: 静态变量初始化顺序
Constant objects have internal linkage, so you get a separate copy of CONST
in each compilation unit that includes const.h
. 常量对象具有内部链接,因此,在包含
const.h
每个编译单元中,您将获得一个单独的CONST
副本。 In this case, you'll get one in main.cpp
, and one in class.cpp
. 在这种情况下,您将在
main.cpp
获得一个,而在class.cpp
获得一个。 You also have your two global objects in main.cpp
. 您还可以在
main.cpp
拥有两个全局对象。
C++ does not define the order in which global objects in different compilation units are initialised. C ++没有定义初始化不同编译单元中的全局对象的顺序。
A
s constructor is called from main.cpp
, and needs the global constant from class.cpp
, which may not yet be initialised. 从
main.cpp
调用A
s构造函数,并需要从class.cpp
调用该全局常量,该全局常量可能尚未初始化。 In your particular case, it hasn't been, so you get the incorrect value you saw. 在您的特定情况下,还没有,所以您得到的值是不正确的。
B
s constructor is inline, so it uses the global constant from main.cpp
, which has been initialised since it is defined earlier in the same compilation unit. B
的构造函数是内联的,因此它使用main.cpp
的全局常量,因为它是先前在同一编译单元中定义的,因此已初始化。
By making the constant a function-static object, it is now guaranteed to be initialised when that function is first called. 通过使常量成为函数静态对象,现在可以保证在首次调用该函数时对其进行初始化。
I don't see the contents of const.h
anywhere so I can only guess what CONST
is (a macro?). 我在任何地方都看不到
const.h
的内容,因此只能猜测CONST
是什么(宏?)。
That aside, in your code example, the member variable A::a
is not initialized. 除此之外,在您的代码示例中,成员变量
A::a
未初始化。 Hence, it could have any value - it's uninitialized. 因此,它可以具有任何值-未初始化。
如果我正确理解了您的问题,那么我相信问题是因为未定义任何全局对象的初始化顺序。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.