我应该'删除'这个CDC吗?

时间:2010-05-19 14:26:47

标签: c++ windows winapi

民间,     我正在尝试追踪现场出现的间歇性错误。 我有一种感觉,就是在一些GDI代码中,我要拼凑起来让一台打印机工作。

我对如何删除此CDC感到困惑,我的代码看起来还不错,但这是正确的。

// Create a device context for printing
CDC* dc = new CDC();
    if(! dc->CreateDC(safeDriverName.AsBSTR(), safePrinterName.AsBSTR(), NULL, NULL))
{
     throw . . . 
}

// as I finish with the CDC
dc->DeleteDC();
delete dc;

delete dc之后我需要dc->DeleteDC();吗?

由于

3 个答案:

答案 0 :(得分:9)

由于您在堆上分配了dc,是的,您确实需要删除dc。不仅如此,如果你按照自己的意愿保留代码,那么在你投掷之前你也应该有一个delete dcDeleteDC函数与dc的分配内存无关。

你可以简化这个:

// Create a device context for printing
CDC dc;
if(! dc.CreateDC(safeDriverName.AsBSTR(), safePrinterName.AsBSTR(), NULL, NULL))
{
     throw . . . 
}

// as I finish with the CDC
dc.DeleteDC();

更新:正如@Fred所提到的,CDC的析构函数会为您调用DeleteDC()

答案 1 :(得分:5)

我喜欢布莱恩的回答。但是如果出于某种原因需要动态分配(可能是堆栈空间问题),请使用智能指针。我可能更喜欢boost :: scoped_ptr,但auto_ptr就足够了:

// Create a device context for printing
auto_ptr<CDC> dc(new CDC());
    if(! dc->CreateDC(safeDriverName.AsBSTR(), safePrinterName.AsBSTR(), NULL, NULL))
{
     // dc is automatically cleaned up on the throw
     throw . . . 
}

// dc is automatically cleaned up at scope exit

答案 2 :(得分:0)

在堆上分配CDC对象以节省堆栈内存 - 这太荒谬了! (请原谅我的苛刻语言)。

这是一个小对象,只有16个字节(在Win32架构上)。它只是4个“整数”变量。 实际上可以使用原始HDC(只有一个“整数”),但由于某种原因,MFC的包装器还定义了另外3个变量。

除了不需要的代码之外,在堆上分配内存会导致严重的性能下降。它还有很大的内存开销,还需要另一个变量(指向已分配内存的指针)。因此浪费的整体内存要多得多。此外,当使用指向动态分配数据的指针时,实际上还有一个额外的间接。

如果分配的对象的大小与总可访问堆栈大小相当,则必须担心会占用过多的堆栈内存。假设在Win32上,默认线程堆栈大小为1MB,我担心从几十KB开始分配对象。或者,您应该担心是否广泛使用深度递归(然后将所有分配的局部变量乘以递归深度)。

但是分配16个字节“以节省堆栈内存” - 与可怕的性能下降,代码复杂性,内存碎片等相比,这听起来很疯狂。