2010-04-27 166 views
4

我有一個奇怪的問題,顯然沒有被初始化,因爲它應該是一個靜態變量。
我有一個運行Windows和Linux的巨大項目。由於Linux開發人員沒有這個問題,我建議這是某種有線Visual Studio的東西。

頭文件靜態變量未初始化

class MyClass 
{ 
    // some other stuff here 
    ... 
    private: 
     static AnotherClass* const Default_; 
}; 


CPP文件

AnotherClass* const MyClass::Default_(new AnotherClass("")); 
MyClass(AnotherClass* const var) 
{ 
    assert(Default_); 
    ... 
} 

問題是,Default_總是NULL。我也在該變量的初始化時嘗試了一個斷點,但我無法捕捉到它。

另一個班有類似的問題。
CPP文件

std::string const MyClass::MyString_ ("someText"); 
MyClass::MyClass() 
{ 
    assert(MyString_ != ""); 
    ... 
} 

在這種情況下MyString_總是空的。所以再次沒有初始化。
有沒有人有關於此的想法?這是一個Visual Studio設置問題嗎?
乾杯西蒙

編輯:
我也遇到了靜態初始化慘敗。但我不確定這是否會成爲問題,因爲Linux編譯器沒有問題。編譯器在這種情況下不應該以同樣的方式作出反應嗎?

+0

嘗試從頭開始創建一個新項目,看看它是否發生在那裏以及 – shoosh 2010-04-27 10:57:00

+0

對不起,不行。正如我所說這是一個非常大的項目。 – 2010-04-27 10:57:43

+1

我假設第一個例子是一個錯字,應該是'AnotherClass * const MyClass :: Default_(new AnotherClass(「」));' – 2010-04-27 10:59:22

回答

6

我建議你使用靜態變量,而不是靜態變量本身靜態成員函數:

class MyClass 
{ 
    // some other stuff here 
    ... 
    private: 
     static AnotherClass* const getAnotherClass(); 
}; 

AnotherClass *const MyClass::getAnotherClass() 
{ 
    static AnotherClass *const p = new AnotherClass(""); 
    return(p); 
} 

標準的保證,當函數被調用首次p被初始化一次,所以你總是會得到正確初始化的對象(除非你已經耗盡內存或構造函數拋出)。

請注意 - 這可能是也可能不是線程安全的(取決於你的編譯器)。

還有一個注意事項 - 現在你必須忍受「內存泄漏」,因爲它幾乎不可能決定何時銷燬對象,並且你沒有辦法將p重置爲NULL。

+0

在這種情況下使用指針是不好的。一個簡單的實例化,然後返回一個引用會好得多。畢竟,一旦你刪除了NULL的可能性,是不是'* const'語義等價於'&'? – 2010-04-27 14:45:10

+0

@Matthieu:我只是按照給出的代碼。對於你的評論 - 你可能是對的,但它取決於AnotherClass的功能(例如,它可能會佔用數據段中的所有空間,所以沒有其他全局變量可用)。 – Tomek 2010-04-27 18:04:21

+0

我同意爲了不使數據段或堆棧飽和(我希望這裏有'Go'這樣的......),可能需要使用*堆*,但是我認爲它應該被保留爲特殊情況(大對象)並推遲到必要時。 – 2010-04-28 06:19:30

0

作品在我的機器(TM):

#include <iostream> 
#include <cassert> 

class AnotherClass 
{ 
public: 
    AnotherClass(const char*) {} 
}; 

class MyClass 
{ 
public: 
    MyClass(AnotherClass* const var); 
private: 
    static AnotherClass* const Default_; 
}; 

AnotherClass* const MyClass::Default_(new AnotherClass("")); 

MyClass::MyClass(AnotherClass* const var) 
{ 
    assert(Default_); 
    std::cout << "Worked!\n"; 
} 

int main() 
{ 
    MyClass tester(NULL); 
    return 0; 
} 

我想的問題是,被稱爲另一個靜態變量的構造。靜態變量的初始化並不總是以你想要的順序發生。

+0

但在他的第二個例子中,他記得'MyClass ::',所以它可能只是一個錯字。 – 2010-04-27 11:00:21

+0

是的,它應該是,只是一個錯字,但謝謝。 – 2010-04-27 11:00:44

+0

你的例子也適用於我。 – 2010-04-27 11:14:59

3

如果在初始化其他一些靜態變量時發生這種情況,您可能會看到static initialization fiasco

+0

這是一個Visual Studio編譯器相關的問題?或者一個普遍的問題? – 2010-04-27 11:19:56

+0

@Simon:這是一個普遍問題。 – sth 2010-04-27 11:42:41

+0

所以它不能成爲我的問題,因爲Linux開發人員沒有類似的問題... – 2010-04-27 11:45:03

2

不應該在這種情況下編譯器反應相同的方式嗎?

不,據我瞭解,個別編譯單元的初始化順序是UNDEFINED。所以Linux開發者很幸運。今天。明天,誰知道?