2012-10-05 47 views
3

在這本書中的C++編程語言,由Bjarne Stroustrup的,作者說:爲什麼構造Zlib_init類Zlib_init書中保密由Bjarne Stroustrup的

有時,當你設計一個圖書館,它是必要的,或者簡單的方法來創建一個帶有構造函數和析構函數的類型,其唯一目的是初始化和清理。這種類型只能使用一次:分配一個靜態對象,以便調用構造函數和析構函數。例如:

class Zlib_init 
{ 
    Zlib_init() ; //get Zlib ready for use 
    ~Zlib_init() ; //clean up after Zlib 
}; 
Class Zlib 
{ 
    static Zlib_init x; 
//... 
}; 

不幸的是,它不能保證這樣的對象是在第一次使用之前進行初始化,並在由單獨編譯單元的程序其最後使用後被銷燬。

爲什麼作者將構造函數和析構函數保持爲私有成員? 如果我們在一個由單獨編譯的單元組成的程序中使用它,爲什麼不能使用這種方法? 它不需要定義成員x調用構造函數Zlib_init()和析構函數~Zlib_init()?那麼這種方法有什麼用處? 它在本書的第10.4.9節。

+2

這是不會編譯 - 出於多種原因 –

+1

似乎比工作代碼的實際演示多個解說...... – nneonneo

回答

8

爲什麼作者將構造函數和析構函數保持爲私有成員?

構造&析構函數是private似乎是一個錯字。
類別static成員需要爲定義爲以便您可以使用他們。爲了定義靜態成員x,構造函數需要可訪問。如果不是,鏈接器會抱怨未定義的引用。

Online Sample

class Zlib_init 
{  
    Zlib_init() ; //get Zlib ready for use 
    ~Zlib_init() ; //clean up after Zlib 
    public: 
    int j; 
}; 
class Zlib 
{ 
    public: 
    static Zlib_init x;  
}; 

Zlib_init Zlib::x; 

int main() 
{ 
    Zlib::x.j = 10; 

    return 0; 
} 

輸出:

prog.cpp:3: error: ‘Zlib_init::Zlib_init()’ is private  
prog.cpp:14: error: within this context  
prog.cpp: In static member function ‘static void Zlib::__static_initialization_and_destruction_0(int, int)’:  
prog.cpp:4: error: ‘Zlib_init::~Zlib_init()’ is private  
prog.cpp:14: error: within this context  

爲什麼會如果我們不採用這種方法的工作它由seperately編制單位的計劃?

如果通過修復或making the constructor and destructor public通過使Zlib a friend of class Zlib_init的代碼仍然面臨着另一個問題,上面提到的錯字。
這個問題在C++中被廣爲人知地稱爲靜態初始化Fiasco

良好閱讀:

[10.14] What's the "static initialization order fiasco"?
[10.17] How do I prevent the "static initialization order fiasco" for my static data members?

+1

感謝您的答覆和對靜態初始化慘敗的附加信息.. – sajas

+0

錯字時有發生時間在B.Stroustrup的書籍和文章中。我猜,這是他心中寫的代碼。沒有時間測試。 – SChepurin

1

爲什麼作者保持構造函數和析構函數作爲私有成員?

我只是猜測,但我認爲作者將聲明剝離到最低限度的必要條件來表達他的想法。儘管一個struct而不是class本可以工作,並且在他的書的其他地方,作者在這種情況下使用省略號(...)。所以我不確定。

如果我們在一個由單獨編譯的單元組成的程序中使用它,爲什麼不能使用這種方法?

靜態對象將main之前運行的構造,所以如果你只使用在東西從main稱爲Zlib,一切正常。如果其他編譯單元中的其他靜態對象嘗試在其構造函數中使用Zlib,則會出現問題。對這兩個構造函數的執行順序沒有任何保證,所以最終可能會有一些代碼嘗試使用未初始化的類Zlib

相關問題