2012-02-23 56 views
8

在C++中使用Direct3D時,我可以編寫一個包含「ID3D11Buffer * vertexBuffer_」的「Cube」類,並確保該Cube對象的析構函數調用vertexBuffer _-> Release()。以D語言釋放資源

我可以具有包含「的unique_ptr cube_」對象「場景」類。所以我知道,當我刪除我的場景時,多維數據集將被刪除,並且因此會調用正在使用的D3D資源的發佈。

在D我不能這樣做。我可以編寫析構函數,但我不知道何時會被調用。如果GC不要求他們可能永遠不會被稱爲記憶...

那麼,什麼是處理這種事情在d的最佳方式?我可以爲每個對象釋放一個「Free」成員函數,釋放它自己的所有資源,並在它擁有的任何對象上調用「Free」,但這似乎是一種容易出錯的手動操作,並且從C++退步。

D有沒有更好的方法來處理這種事情?

回答

6

你可以在棧上使用一個結構。 有確定性的破壞。你甚至可以通過使用std.typecons.RefCounted來重新計算它。如果你想保證析構函數運行,不要在堆上使用結構。目前,我認爲如果結構體的析構函數堆積如山,就不會運行,因爲GC沒有它需要的信息(這應該被固定在未來雖然)。

但如果你堅持把它在堆上的一類,並且要明確地破壞對象,那麼你可以調用它clear

clear(obj); 

,將調用該對象的析構函數和然後將其置於無效狀態,任何試圖在此之後使用它的應用程序都會炸燬(IIRC,虛擬表將被清零)。但內存並沒有真正釋放。這是GC的工作。並且不要使用delete。它將被棄用。我真的很驚訝它還沒有出現,因爲它已經計劃好幾年了才能擺脫它。

當然,一種選擇是有一個明確的功能,您調用釋放資源。這是不是一個好主意取決於你在做什麼。但無論如何,課程都是由GC收集,而不是在您選擇時自由釋放。

工作正在進行自定義分配器,這將給你更多的選擇如何分配一個類,其中的一個可能會讓你有更多的確定性的類的破壞,但還沒有準備好。

如果你感到瘋狂,你可以使用std.typecons.scoped,它取代了即將棄用類型修飾符scope(雖然scope在其他情況下堅持圍繞 - 如scope語句)。它在堆棧上放置一個類。但這是不安全的(這就是爲什麼scope在這種情況下會消失的原因),並且如果要將對象粘貼到堆棧上,您可能還需要使用一個結構。

編輯:您還可以使用mallocfreestd.conv.emplace把對象分配的內存塊的非GC像你有C++,但我認爲你必須顯式調用析構函數讓它運行,因爲free不瞭解析構函數(它是一個C函數)。這將有利於使內存隨資源一起消失(而在GC堆上的對象上使用clear只會摧毀對象的內容,而不會釋放內存),但我不知道那會給你帶來多大的收益在GC分配的對象上使用clear

然而,然後你可以創建一個類似new免費功能,爲你做的mallocemplace,再有類似delete自由函數調用析構函數和free,這將使你相同的情況下爲C++ 。事實上,我想知道這是否足夠有用,使其成爲標準庫。這可能是最終會在自定義分配器中發生的事情。因此,它不會讓我感到吃驚可言,如果在不久的將來,你可以使用自定義分配器做類似

auto obj = customAllocObj.create!MyObj(args); 
//Do stuff... 
customAllocObj.destroy(obj); 

而且我認爲這將解決你的問題相當好因爲這是本質與C++中的一樣,只是使用庫函數而不是內置的newdelete。我想我會在新聞組上提出來。我預計至少有一些人會喜歡這樣的功能,而且這似乎很適合自定義分配器。

+0

謝謝您的全面回答! 我不確定我可以在棧上使用一個結構體,因爲我的對象的生命週期比它長。明確可能適用於我,但它與我自己的clear()函數似乎沒有什麼不同。 Ypu've給了我更多的東西要考慮:) – jcoder 2012-02-23 11:25:33

+0

@JohnB我假設你可能會傳遞結構,但它肯定是真的,這可能無法正常工作,這取決於你的情況。如果你自己做了一些函數,我建議不要在其中調用析構函數 - 這只是要求麻煩(儘管析構函數可以調用任何可以釋放資源的函數)。所以,如果你真的想調用析構函數,那麼使用'clear'。如果你想要做的只是釋放資源,那麼專門調用另一個函數可能更有意義,而不是銷燬該對象。這取決於你的代碼。 – 2012-02-23 18:59:46

2

只是爲了澄清:析構函數是總是調用。如果一個對象在應用程序關閉時尚未完成,GC將運行其終結器。

我看不出如何手動調用free()函數來刪除頂點緩衝器是任何更多的錯誤比具有在C手動管理存儲器++容易發生。無論如何,你可能想看看:http://www.dlang.org/phobos/std_typecons.html#scopedhttp://www.dlang.org/phobos/std_typecons.html#RefCounted

+2

問題是當內存被釋放時會調用析構函數,這將在將來某個時刻GC注意到對象不再被引用時調用。我需要立即釋放D3D對象,而不是在將來某個未定義的點處... – jcoder 2012-02-23 10:11:19

+0

['delete'](http://www.d-programming-language.org/expression.html#DeleteExpression)? 「如果UnaryExpression是一個類對象引用,並且存在該類的析構函數,則會爲該對象實例調用析構函數。」 – 2012-02-23 10:27:13

+0

'delete'正在從語言中刪除。不要使用它。你可以使用'clear',它將調用對象的析構函數並使對象無效,但它不會釋放內存。這是GC的工作。如果你想確定性破壞,那麼使用一個結構。 – 2012-02-23 11:03:30