2012-08-02 65 views
0

我廣泛使用boost共享指針,所以我創建了一個有用/通用功能的類。作爲其中的一部分,我想創建一個靜態成員函數來包裝boost :: make_shared來分配/構造對象的實例。例如,如果A類具有構造函數:C++自動生成包裝boost :: make_shared

class A { 
    A(int arg1, double arg2); 
    ... 
} 

然後圍繞make_shared看起來像這樣相應的包裝:

class A { 
    A(int arg1, double arg2); 
    static boost::shared_ptr<A> MakeShared(int arg1, double arg2) { 
    return boost::make_shared<A, int, double>(arg1, arg2); 
    } 
    ... 
} 

然後創建一個實例,你只是做:

boost::shared_ptr<A> a_ptr = A::MakeShared(1, 2.3); 

顯然,構造函數和MakeShared之間的關係是非常機械的,所以我的問題是是否有可能創建一個預處理宏或基類,它可以自動生成cally爲每個構造函數製作一個MakeShared版本?這樣的代碼只是看起來是這樣的:

class A { 
    A(int arg1, double arg2); 
    A(int arg1, double arg2, bool arg3); 
    ... 
    DEFINE_CORRESPONDING_MAKE_SHARED_FUNCTIONS 
    ... 
} 

使用升壓預處理程序庫(或其他庫)是好的,但較大的項目還沒有準備好使用C++ 11,所以希望我們能夠避免那。

+6

這真的需要嗎? make_shared可以推導出類型,因此make_shared (1,2.3)正常工作。 – ThirdOne 2012-08-02 04:18:02

+0

哦,我不知道make_shared可以推斷出類型 - 我試圖避免做類似make_shared (1,2.3)的東西,這對於1或2個參數來說不算太壞,但對於更多爭論和/或更復雜的類型而言,會變得非常繁瑣和繁瑣。你如何使函數/模板能夠推斷出這樣的參數?作爲普遍感興趣的一點,我想知道如何編寫我自己的函數來實現這一點。 – Ken 2012-08-02 17:50:23

+0

沒關係 - 我只是查了一下,你所要做的就是在參數中使用模板參數,然後它可以從尖括號中省略。即'template void f(T arg);'可以用'int i = 1; f(i)'相當於'f (i)'。我只是不知道C++的這個小功能。感謝您的建議! – Ken 2012-08-02 18:02:21

回答

1

這可以預先定義的數量的參數來實現:

#define DEFINE_MAKE_SHARED_FUNCTIONS(CLASS_TYPE) \ 
    template<typename A1> \ 
    static boost::shared_ptr<CLASS_TYPE> make_shared(const A1& a) {\ 
     return boost::make_shared<CLASS_TYPE>(a);\ 
    }\ 
    template<typename A1,typename A2> \ 
    static boost::shared_ptr<CLASS_TYPE> make_shared(const A1& a, const A2& a2) {\ 
     return boost::make_shared<CLASS_TYPE>(a, b));\ 
    } 

如果你想獲得看上你可以使用升壓預處理程序自動執行宏,但你可以很容易地實現所有的N個版本在一個宏中(可能編譯得更快)。

您可以使用veridic模板來減少對宏的需求,但目前不可移植(不支持VC++)。

此外,我質疑這個作爲make_shared(args ...)的需求本身。

+0

你還沒有意識到你正試圖在靜態成員函數中使用這個指針。 – 2012-08-03 02:19:42

+0

egad ...你是對的。爲宏的參數添加類型。 – bytemaster 2012-08-03 02:56:42