简体   繁体   English

全局const初始化以及.h或.cpp文件中的构造函数之间的差异

[英]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: 我不知道如何解释它,所以这是代码:

main.cpp main.cpp中

#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;
}

class.h class.h

#ifndef CLASS_H
#define CLASS_H
#include "const.h"

class A {
public:
A();
float a;
};

class B {
public:
B():b(CONST){}
float b;
};
#endif

class.cpp class.cpp

#include "class.h"
A::A()
: a(CONST){}

const.h const.h

#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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM