[英]Global const initializing and difference between constructor in .h or .cpp file
我想知道為什么有時在單獨的.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類卻沒有?
不保證在不同翻譯單元中全局對象的初始化順序。
請看一下這個stackoverflow問題: 靜態變量初始化順序
常量對象具有內部鏈接,因此,在包含const.h
每個編譯單元中,您將獲得一個單獨的CONST
副本。 在這種情況下,您將在main.cpp
獲得一個,而在class.cpp
獲得一個。 您還可以在main.cpp
擁有兩個全局對象。
C ++沒有定義初始化不同編譯單元中的全局對象的順序。 從main.cpp
調用A
s構造函數,並需要從class.cpp
調用該全局常量,該全局常量可能尚未初始化。 在您的特定情況下,還沒有,所以您得到的值是不正確的。 B
的構造函數是內聯的,因此它使用main.cpp
的全局常量,因為它是先前在同一編譯單元中定義的,因此已初始化。
通過使常量成為函數靜態對象,現在可以保證在首次調用該函數時對其進行初始化。
我在任何地方都看不到const.h
的內容,因此只能猜測CONST
是什么(宏?)。
除此之外,在您的代碼示例中,成員變量A::a
未初始化。 因此,它可以具有任何值-未初始化。
如果我正確理解了您的問題,那么我相信問題是因為未定義任何全局對象的初始化順序。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.