民间, 我正在尝试追踪现场出现的间歇性错误。 我有一种感觉,就是在一些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();
吗?
由于
答案 0 :(得分:9)
由于您在堆上分配了dc
,是的,您确实需要删除dc
。不仅如此,如果你按照自己的意愿保留代码,那么在你投掷之前你也应该有一个delete dc
。 DeleteDC
函数与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个字节“以节省堆栈内存” - 与可怕的性能下降,代码复杂性,内存碎片等相比,这听起来很疯狂。