代码之家  ›  专栏  ›  技术社区  ›  Binary Worrier

我应该“删除”这个CDC吗?

  •  1
  • Binary Worrier  · 技术社区  · 16 年前

    我正试图追踪一个出现在网站上的间歇性错误。 我有一种感觉,这是在一些GDI代码,我想拼凑起来,让理货打印机工作。

    // 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 回复  |  直到 16 年前
        1
  •  9
  •   Brian R. Bondy    16 年前

    dc 在堆上,是的,您确实需要删除 直流 delete dc 在你扔之前。这个 DeleteDC 函数与所分配的内存无关

    不过,您可以简化为:

    // 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() 为你。

        2
  •  5
  •   Fred Larson    16 年前

    我喜欢布赖恩的回答。但如果出于某种原因需要动态分配(可能是堆栈空间问题),请使用智能指针。我可能更喜欢boost::scoped\u ptr,但auto\u 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
    
        3
  •  0
  •   valdo    16 年前

    分配 CDC 对象来节省堆栈内存-这太荒谬了(恕我直言)。

    它是一个小对象,只有16个字节(在Win32体系结构上)。只有4个“整数”变量。 HDC (这只是一个“整数”),但是出于某种原因,MFC的包装器定义了另外3个变量。

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

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