簡體   English   中英

C ++ RAII問題

[英]C++ RAII Questions

正如我理解它正確實現RAII,如果我在哪里調用CreateFont ,我會將它包裝在構造DeleteObject中的CreateFont和析構DeleteObject中的DeleteObject中,因此當它超出范圍時將其清除。

第一個問題是,我最終會不會有大量的課程嗎? 特別是因為類只有構造函數和析構函數。

第二個問題是,如果我在WndProc中調用CreateFont類,那么它會不斷超出范圍。 所以我應該做我的所有來電CreateFont或類似LoadBitmap在WndMain? 我習慣在WM_CREATE調用這些函數並在WM_DESTROY清理它們。

通過使用模板來幫助您,您可以避免大量重復工作。 例如,如果您使用boost::shared_ptr您可以執行以下操作:

#include <boost/shared_ptr.hpp>
#include <functional>

struct Font;

Font *createFont();
void deleteFont(Font*);

int main() {    
  boost::shared_ptr<Font> font(createFont(), std::ptr_fun(deleteFont));
}

這樣可以節省您編寫自定義類來管理資源的過程。 如果你沒有使用boost TR1或更新版本,你仍然可以自己實現類似和通用的東西來提供幫助。

boost::shared_ptr是正確引用計數的,所以如果你想在某個地方創建它並“促進”它以后活得更久你可以通過將它復制到它死亡之前的某個地方來實現。

第一個問題是,我最終會不會有大量的課程嗎? 特別是因為類只有構造函數和析構函數。

是的,但有幾點需要考慮:

  • 這是個問題嗎? 這些課程很小,易於閱讀和理解,
  • 您可能能夠重用其中的許多(例如,有很多Win32函數可以創建HANDLE對象,並且它們都以相同的方式關閉(使用CloseHandle ),因此您可以為這些函數重用相同的類。
  • 您可以使用智能指針或其他通用包裝器來填充大部分樣板代碼。 最流行的智能指針類允許您指定自定義刪除功能。

第二個問題是,如果我在WndProc中調用CreateFont類,那么它會不斷超出范圍。

將其存放在不會過早超出范圍的位置。 :)在這里,智能指針可能再次有用。 例如,只要至少有一個shared_ptr指向它, shared_ptr就可以用來保持字體的活動狀態。 然后你可以簡單地將它從函數傳遞到一些常見的長壽命位置。

否則,只要您為RAII類實現復制構造函數和賦值運算符(在C ++ 11中,您可能希望實現移動構造函數並移動賦值),就可以將其安全地復制(或移動)到您想要放置的任何位置它,即使它是在較小的范圍內創建的。

第一個問題是,我最終會不會有大量的課程嗎? 特別是因為類只有構造函數和解構函數

如果您不喜歡為每種不同類型的對象創建的類數,可以創建一個RAII類,它在構造函數中接受HGDIOBJ參數並在析構函數中調用DeleteObject。 然后,此類可用於所有不同的GDI對象。 例如:

class GDIObject
{
public:
    HGDIOBJ GdiObject;

    GDIObject( HGDIOBJ object )
        : GdiObject( object )
    {
    }

    ~GDIObject()
    {
        DeleteObject( GdiObject );
    }
}

...

GDIObject font( CreateFont( 48, 0, 0, 0, FW_DONTCARE, false, true, false, DEFAULT_CHARSET, OUT_OUTLINE_PRECIS, CLIP_DEFAULT_PRECIS, CLEARTYPE_QUALITY, VARIABLE_PITCH, TEXT("Impact") ) );

第二個問題是,如果我在WndProc中調用CreateFont類,那么它會不斷超出范圍。 所以我應該完成對CreateFont的所有調用或者像WndMain中的LoadBitmap嗎? 我習慣在WM_CREATE中調用這些函數並在WM_DESTROY中清理它們。

對於需要在內存中保留的時間長於函數范圍的項目,您必須將它們放在全局級別。

如果你想要堅實的RAII,有一些選項可以減少你需要的類的數量 - 例如,一些boost智能指針(具體是shared_ptr)允許你提供自己的函數來在指針離開時調用范圍。

否則,是的 - 你將擁有一個需要顯式釋放的任何資源的類 - 雖然它在代碼方面很痛苦,但從長遠來看,它將為你節省大量的調試時間(特別是在小組項目中)。 我仍然會根據你自己對情況的看法來使用RAII--在任何地方使用它都是一個好主意,但有時在轉換舊代碼時,修復所有調用鏈可能需要大量工作。使用它。

還有一件事 - 我對你正在使用的GUI邏輯不太熟悉,所以我不會專門去那里......但你必須研究你的資源應該如何復制以及應該多長時間保持。 您的RAII容器是引用計數,還是它們具有值(復制)語義? 像shared_ptr這樣的引用計數智能指針可以解決您經常重新創建資源的問題,只要您可以在代碼周圍傳遞對原始文檔的引用即可。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM