2011-05-17 67 views
0

我正在寫在C的套接字監聽每當接受,它會創建一個新的線程(分離)的recv的數據和流程。析構函數/回調下獲得shared_ptr的水煤漿

但每次,我需要手動調用close(socket_descriptor)。如果它是C++,我可以在某種程度上選擇在析構函數中關閉它。

我試圖找出的東西,爲我提供了相同的行爲。
基本上,我想要創建類似於C中的shared_ptr。

C中是否有一個可以在對象超出範圍時獲取信號或通知的地方?

+2

沒有。爲什麼不用C++編寫程序? – 2011-05-17 12:25:41

+0

@尼爾,把我的話說出來......鍵盤 – Marlon 2011-05-17 12:37:25

+0

個人原因不使用C++ ...大聲笑 – Mayank 2011-05-17 12:46:42

回答

3

不,這不是C的固有特徵...使像你問什麼,你就必須建立某種形式的回撥機制,將使用查表來匹配對象到它的「destrutor」,並且在你寫的每個函數的末尾或者更可能的是,在聲明對象的每個範圍的末尾調用該通用回調函數。我認爲這非常混亂和複雜,最後,這可能比它的價值更麻煩,也就是說,你可以簡單地使用goto並將所有清理代碼寫在函數的最後(我知道 - 通常使用goto被認爲是非常糟糕的風格,但對於在函數結束時跳轉到清理代碼,它們實際上可以使代碼更清潔,而不是每次都重複相同的清理代碼時間有錯誤)。

例如,假設你有分配一些內存,並在函數一些早期的點開了一個文件描述符一個函數,但如果有一些錯誤,無法繼續...你不能簡單地返回錯誤代碼,您必須對做一些清理工作,但它會一遍又一遍地權代碼的中間再重複清理代碼疼痛:

int my_function() 
{ 
    int* array_on_heap = malloc(ARRAYSIZE * sizeof(int)); 
    int file_descriptor; 

    //...some code 

    if (some_ptr == NULL) 
     goto error_cleanup; 

    //...some more code 

    if (some_other_pointer != some_ptr) 
     goto error_cleanup; 

    //...even more code 

    //normal return with no error 
    return 0; 

    error_cleanup: 
     //clean-up code in case there was an error 
     free(array_on_heap); 
     close(fd); 
     return -1; 
} 

這種故意和明智地使用的goto這裏創建了一個功能非常簡潔的區域,可以在其中進行銷燬和清理,並且您不必擔心可能會遺漏清理功能,因爲您決定在實際中噴灑清理代碼l函數本身的「機制」。

+0

簡單地返回函數會更好一個錯誤代碼。作爲一個經驗法則,處理分配的代碼模塊是負責清理的代碼模塊。 – Lundin 2011-05-17 12:41:56

+0

取決於...假設有一個錯誤,但是你已經在堆上分配了內存,或者在函數的一個更早的點上打開了一些文件等等?在這種情況下,你不能簡單地返回一個錯誤代碼,並且把所有其他事情都放在一邊。你必須清理它。 – Jason 2011-05-17 12:49:41

0

只有一個你做的「原始」 C方式:

void abc_init (parameters); 

void abc_cleanup (parameters); 

所有ABC功能屬於模塊ABC,其中包括abc.h和abc.c.的對象的分配然後可以被調用者來處理的ABC模塊,或模塊本身:

// alternative 1, leave allocation to the caller 

#include "abc.h" 

int main() 
{ 
    Abc_t x; 

    abc_init(&x); 

    ... 

    abc_cleanup(&x); 
} 


// alternative 2, the module handles allocation 

// abc.c 

static Abc_t* x; 

void abc_init (parameters) 
{ 
    x = some_sort_of_allocation(); 
    set x based on parameters 
} 


... 

void abc_cleanup (parameters) 
{ 
    cleanup x 
} 
1

有沒有這樣的事情在普通的舊C.自動析構函數你有沒有考慮這樣做,通過垃圾回收器

例如,您可以使用Boehm-Demers-Weiser conservative garbage collector分配對象,然後在對象變得不可訪問時調用GC_REGISTER_FINALIZER來關閉套接字描述符。

另一種解決辦法是包客戶端的回調函數將其簡單地調用回調函數,然後關閉套接字另一個函數。這樣你就不必在每個回調函數中明確地關閉它。

相關問題