處置

2014-11-08 55 views
0

假設以下兩類:處置

struct A { 
    A() {} 
}; 

struct B { 
    B(const A& a) {} 
}; 

它發生在我多次遇到這樣的情況,我必須以建立創建一個類的臨時實例我需要使用的一個實例。喜歡的東西:

A a; 
// Do very complex computations using a; 
B b(a); 
// use b, a is not needed anymore. 
return make_result(b); 

我的問題是,有時我的計算後a持有的資源可以是顯著的,我實例b後,我想將他們釋放。與此同時,整個過程a -> b -> result在邏輯上是一個非常緊湊的東西,我想避免把它分解成函數,因爲在這種情況下會有pretty much nothing to gain

C++中有哪些可用的解決方案來解決這類問題?

+0

我真的不明白你的問題是什麼。如果您需要保持A對'result'使用的資源有意義,請保留它們。如果你不這樣做,通常在A的析構函數中釋放它們。所有「在C++中可用的解決方案」都是* that *:釋放你沒有使用的東西。 – meagar 2014-11-08 15:08:02

+2

將'a'移動到'b'? 'b b(std :: move(a));' – pmr 2014-11-08 15:08:16

+0

'b'通常不需要保留'a',只是爲了處理它的內部。問題是你不能真的調用'''析構函數。你會怎麼做? 'a'通常不會被破壞,直到它的作用域結束。它的作用域必須包含整個'b',因爲'b'只能用'a'創建。 – Svalorzen 2014-11-08 15:13:19

回答

0

很大程度上取決於您在程序中製作的類。 AB必須具有公共協議(或其他類的子協議)以及暗示該協議的公共存儲(例如某些定製structvector)。如果是這種情況,負責的類可以具有資源代理(如set_owner)的功能,這是另一個類可以使用的功能。該模式很大程度上(或完全)取決於您擁有的類/資源/模式。

如果存在一些通用協議,則可以適當地更改一個或兩個(或多個)類。

如果類相似(例如涉及繼承或嵌套類),則可以使用返回值優化,Name-RVO或move構造。

1

你可以默認構造的對象分配到A,假設A的賦值操作符正常釋放‘資源’:

A a; 
// Do very complex computations using a; 
B b(a); 
a = {}; 
// use b, a is not needed anymore. 
return make_result(b); 

你可以改變B通過值採取A和移動構建A實例到B

struct A { 
    A() {} 
}; 

struct B { 
    B(A a) {} 
}; 
// ... 
A a; 
// Do very complex computations using a; 
B b(std::move(a)); 
// use b, a is not needed anymore. 
return make_result(b); 

它具有很好的優勢B的構造都不可能‘偷’resou來自A的對象。

你可以使用lambda來構造A,並把它傳遞給B

B b([&]{ 
    A a; 
    // Do very complex computations using a; 
    return a; 
}()); 
// use b, a is not needed anymore. 
return make_result(b); 

你可以既構建A與拉姆達B把它的值:

struct A { 
    A() {} 
}; 

struct B { 
    B(A a) {} 
}; 
// ... 
B b([&]{ 
    A a; 
    // Do very complex computations using a; 
    return a; 
}()); 
// use b, a is not needed anymore. 
return make_result(b); 

它允許BA盜取東西,但不會留下殭屍A實例layin g周圍。

+0

我喜歡lambda的想法,以保持代碼接近,但使用函數語義來確保'a'被刪除。它*確實*看起來有點怪異! – Svalorzen 2014-11-08 15:21:32

+0

@Svalorzen你也可以在函數範圍中定義lambda,並將其分配給某個'auto var_name'並在此之後調用它。 – pmr 2014-11-08 15:22:26