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

时间:2010-12-09 10:25:42

标签: c++ constructor const

我想知道为什么有时我在单独的.h文件中定义的全局const在我需要的时候没有正确初始化。一些测试导致我无法理解的情况。我不知道如何解释它,所以这是代码:

的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

#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

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

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

运行上面的代码后,我得到:

  

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级呢?

4 个答案:

答案 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)

如果我正确理解你的问题,那么我认为问题是因为没有定义任何全局对象的初始化顺序。