2010-01-18 82 views
2

在Stroustrup的書C++編程語言中,他提到「資源按其採集的相反順序發佈通常很重要」 爲什麼順序很重要?爲什麼資源管理命令很重要?

void acquire() 
{ 
acquire resource 1; 
... 
acquire resource n; 
use resources; 
release resource n; 
... 
release resource 1; 
} 

那麼如果我們改變順序如下?

void acquire() 
{ 
    acquire resource 1; 
    ... 
    acquire resource n; 
    use resources; 
    release resource 1; 
    ... 
    release resource n; 
} 

回答

0

資源,在現實世界中的代碼,通常會被嵌套,並且構造一個對象的時候摧毀時,它可用你想要任何可用。由於C++具有確定性的破壞,它必須選擇一些排序,並且FILO(「先入先出」)運行良好。

嵌套的最簡單的例子是類。

struct Base { 
    Base() { cout << "Base\n"; } 
}; 
struct Member { 
    Member() { cout << "Member\n"; } 
}; 

struct Derived : Base { 
    Member member; 
    Derived() { cout << "Derived\n"; } 
}; 

現在你可以添加類似的輸出dtors這個例子:他們總是通過第1構築基地,然後成員,那麼得到的構造函數的體構成。

在Derived被銷燬之前,你不能銷燬Base(派生的dtor可能需要使用它,除此之外);同樣的成員。

4

如果你不這樣做,你可能會陷入僵局或泄漏情況。假設你聲明瞭Obj1並且它分配了Obj2-Obj3。你必須先釋放2和3,然後才能釋放1.在實踐中,儘管這並不值得擔心,因爲構造函數和析構函數會以正確的順序調用。

3

一個原因是你通常有嵌套的內存分配。

E.g. you have a class 
class A{ 
    FILE *fp; 
    char *name; 
    xxx; 
} 

你第一次分配資源對於A使用new A,以後你需要操縱的fpname。因此,當您釋放資源時,需要首先發布fpname,然後再發布A

1

從最一般的意義上說,「它只在重要時才重要」。依賴關係決定了必要的銷燬順序。

這裏的現有答案涉及以反向拓撲順序釋放嵌套資源。

但是,C++還定義了對象中資源的初始化順序。這意味着成員構建可以使用以前初始化的「兄弟姐妹」......意味着他們有依賴關係,這些兄弟姐妹在破壞時仍然有效。

class A { 
    A(std::string *link2str); 
    ~A(); 
    std::string *important_state; 
}; 

class B { 
    string first; // initialization occurs in the order of declaration 
    A second; 
    B() : first(), second(&first) { } // not the constructor's list order 
}; 

不是說這個例子看起來像一個好的設計,但你永遠不知道。 有時成員之間存在某種依賴關係的原因。

相關問題