原創|其它|編輯:郝浩|2009-11-23 11:14:13.000|閱讀 471 次
概述:這里我們將討論的是C#與C++在靜態構造函數上的異同,通過這一關鍵點,希望能讓大家更好的了解C#與C++,也對大家今后的工作有所幫助。
# 界面/圖表報表/文檔/IDE等千款熱門軟控件火熱銷售中 >>
這里我們將討論的是C#與C++在靜態構造函數上的異同,通過這一關鍵點,希望能讓大家更好的了解C#與C++,也對大家今后的工作有所幫助。
在C#中,類的靜態構造函數用于在使用類之前進行相關的初始化工作;比如,初始化靜態成員或執行特定操作。CLR 在第一次創建該類對象或調用該類靜態方法時自動調用靜態構造函數。同時,CLR保證靜態構造函數的線程安全性(準確地說是,只會調用一次,不存在多線程問題)。
下面是MSDN對靜態構造函數特點的描述:
1.靜態構造函數既沒有訪問修飾符,也沒有參數
2.在創建第一個實例或引用任何靜態成員之前,將自動調用靜態構造函數來初始化類
3.無法直接調用靜態構造函數
4.在程序中,用戶無法控制何時執行靜態構造函數
C++語言規范并未包含類似靜態構造函數的東西,但在使用類之前做初始化工作的需求卻是客觀存在的。就滿足需求本身來講,C++完全可以通過手動方式實現,但要處理好初始化時機,線程安全性等問題。本文則嘗試通過C++的模版機制模擬實現靜態構造函數,避免手動初始化的繁瑣實現。對于需要靜態構造函數的類A,只需用繼承static_constructable模版類,并提供 static void statici_constructor()靜態方法即可:
class A : static_constructable<A>
{
public:
static void static_constructor() {
std::cout << "static constructor a" << std::endl;
s_string = "abc"; //初始化靜態數據
}
static std::string s_string;
public:
A(){
std::cout << "constructor a" << std::endl;
}
private:
int m_i;
};
std::string A::s_string;
int _tmain(int argc, _TCHAR* argv[]){
std::cout << "beginning of main" << std::endl;
assert(sizeof(A) == sizeof(int));//繼承不改變A的內存布局
assert(A::s_string == "");
A a1;
assert(A::s_string == "abc");
A a2;
std::cout << "end of main" << std::endl;
return 0;
}
輸出:
beginning of main
static constructor a //創建A對象前自動調用靜態構造方法,一次且僅一次
constructor a
constructor a
end of main
下面是static_constructable類模板的實現:
template<typename T>
class static_constructable
{
private:
struct helper{
helper(){
T::static_constructor();
}
};
protected:
static_constructable(){
static helper placeholder;
}
};
上面的實現把對A::static_constructor()的回調放到內部類helper的構造函數中;并在static_constructable()中定義一個helper局部靜態變量;C++保證在構造派生類 A的對象時,會先調用基類static_constructable的構造函數,且靜態局部變量只會構造一次,這樣就達到調用一次且僅一次A::static_constructor()的目的。< /span>
static_constructor類模板簡單地模擬了C#的靜態構造函數機制,它具有以下特點:
1. 在第一次構造類對象之前自動調用類提供的靜態構造函數
2. 靜態構造函數被調用的時機是確定的
3. 利用了C++的局部靜態變量初始化機制保證了線程安全性(更正:實際并非線程安全,C++標準不涉及多線程問題,而一般編譯器實現也非線程安全,更多參見評論部分)
4. 基于繼承的實現機制并未改變派生類的對象內存布局
不過,和本文開始列出的C#靜態構造函數的幾個特點相比,本實現還有明顯的不足:無法通過調用類A的靜態方法觸發靜態構造函數;類A的靜態構造函數必須是public的。希望有更好解決方案的朋友不吝賜教,也歡迎對此話題感興趣的朋友交流探討!
本站文章除注明轉載外,均為本站原創或翻譯。歡迎任何形式的轉載,但請務必注明出處、不得修改原文相關鏈接,如果存在內容上的異議請郵件反饋至chenjj@fc6vip.cn
文章轉載自:網絡轉載