C# vs C++之三:靜態建構函式

來源:互聯網
上載者:User

在C#中,類的靜態建構函式用於在使用類之前進行相關的初始化工作;比如,初始化靜態成員或執行特定操作。CLR 在第一次建立該類對象或調用該類靜態方法時自動調用靜態建構函式。同時,CLR保證靜態建構函式的執行緒安全性(準確地說是,只會調用一次,不存在多線程問題)。

 

下面是MSDN對靜態建構函式特點的描述:

1.靜態建構函式既沒有存取修飾詞,也沒有參數

2.在建立第一個執行個體或引用任何靜態成員之前,將自動調用靜態建構函式來初始化類

3.無法直接調用靜態建構函式

4.在程式中,使用者無法控制何時執行靜態建構函式

 

C++語言規範並未包含類似靜態建構函式的東西,但在使用類之前做初始化工作的需求卻是客觀存在的。就滿足需求本身來講,C++完全可以通過手動方式實現,但要處理好初始化時機,執行緒安全性等問題。本文則嘗試通過C++的模版機制類比實現靜態建構函式,避免手動初始化的繁瑣實現。對於需要靜態建構函式的類A,只需用繼承static_constructable<A>模版類,並提供 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<A>()中定義一個helper局部靜態變數;C++保證在構造衍生類別 A的對象時,會先調用基類static_constructable<A>的建構函式,且靜態局部變數只會構造一次,這樣就達到調用一次且僅一次A::static_constructor()的目的。< /span>

 

static_constructor類模板簡單地類比了C#的靜態建構函式機制,它具有以下特點:

1. 在第一次構造類對象之前自動調用類提供的靜態建構函式
2. 靜態建構函式被調用的時機是確定的
3. 利用了C++的局部靜態變數初始化機制保證了執行緒安全性(更正:實際並非安全執行緒,C++標準不涉及多線程問題,而一般編譯器實現也非安全執行緒,更多參見評論部分)
4. 基於繼承的實現機制並未改變衍生類別的對象記憶體布局

 

不過,和本文開始列出的C#靜態建構函式的幾個特點相比,本實現還有明顯的不足:無法通過調用類A的靜態方法觸發靜態建構函式;類A的靜態建構函式必須是public的。希望有更好解決方案的朋友不吝賜教,也歡迎對此話題感興趣的朋友交流探討!

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.