15 мая 2023 года "Исходники.РУ" отмечают своё 23-летие!
Поздравляем всех причастных и неравнодушных с этим событием!
И огромное спасибо всем, кто был и остаётся с нами все эти годы!

Главная Форум Журнал Wiki DRKB Discuz!ML Помощь проекту


MFC Exceptions.

Paul Martinsen -- pmartinsen@hort.cri.nz
Tuesday, December 17, 1996

Environment: VC++ 4.0, Win 95

Hello,
  I was testing my error handling code last night & discovered what I 
would call an error in the documentation. In many cases the MFC help 
notes that a function could throw an exception, for example 
CArray::InsertAt throws exceptions when there is insufficient memory 
to insert the element. However, I discovered that it is actually a 
POINTER that is thrown, not a CMemoryException (for example) object, 
in otherwords the following code doesn't catch the error:

try
{ myArray.InsertAt(10,pNewObject);
} catch (CMemoryException)
{ AfxMessageBox(IDS_NO_MORE_MEMORY);
}

The catch line must read:
catch (CMemoryException *)
to catch the exception thrown by InsertAt. I looked at the code that
seems to be used for throwing these, eg AfxThrowMemoryException(),
and it seems to use a pointer to a static object which, of course,
doesn't need to be deleted. Does anybody know if this is always
true, ie do I every have to delete the pointer that I get in the
catch? Also, what is all this business with THROW and CATCH etc, 
instead of the C++ throw & catch? Is this just MFC shouting so we 
notice what is going on :), or should I be using them for my exception 
handling too?

Paul. 



John Addis -- jaddis@erols.com
Wednesday, December 18, 1996

[Mini-digest: 7 responses]

> From: Paul Martinsen 
> To: mfc-l@netcom.com
> Subject: MFC Exceptions.
> Date: Monday, December 16, 1996 7:37 PM
> 
> Environment: VC++ 4.0, Win 95
> 
> Hello,
>   I was testing my error handling code last night & discovered what I 
> would call an error in the documentation. In many cases the MFC help 
> notes that a function could throw an exception, for example 
> CArray::InsertAt throws exceptions when there is insufficient memory 
> to insert the element. However, I discovered that it is actually a 
> POINTER that is thrown, not a CMemoryException (for example) object, 
> in otherwords the following code doesn't catch the error:

All of the ::AfxThrowXxxxException() functions throw pointers rather than
actual objects.

> I looked at the code that
> seems to be used for throwing these, eg AfxThrowMemoryException(),
> and it seems to use a pointer to a static object which, of course,
> doesn't need to be deleted. Does anybody know if this is always
> true, ie do I every have to delete the pointer that I get in the
> catch? 

For CException derived classes you should call the object's Delete()
method. 

Ex: 
  catch(CMemoryException* pME)
  {
    ...
    pME->Delete();
  }


> Also, what is all this business with THROW and CATCH etc, 
> instead of the C++ throw & catch? Is this just MFC shouting so we 
> notice what is going on :), or should I be using them for my exception 
> handling too?

THROW and CATCH were maintained for backwards compatibility with previous
versions of MFC. If you are not concerned with this then you should be okay
using the normal c++ throw/catch keywords.
 
--
John Addis                   http://www.xorbit.com
"Power failure; please turn your computer on."
-----From: Mike Blaszczak 

At 12:37 12/17/96 +1200, Paul Martinsen wrote:

>I looked at the code that seems to be used for throwing these,
>eg AfxThrowMemoryException(), and it seems to use a pointer to
>a static object which, of course, doesn't need to be deleted.

Obviously.  If MFC needed throw a memory exception, where would it
get the memory to create it before throwing it?

>Does anybody know if this is always true, ie do I every have
>to delete the pointer that I get in the catch?

Yes.  Please read the documentation.  It explains that you must
call the Delete() member of CException-derived objects that you
catch.  Like this:


   try
   {
      m_array.InsertAt(11, "Kevin Dineen");
      m_array.InsertAt(35, "Peter Siedorkiewicz");
      m_array.InsertAt(5, "Ulf Samuelsson");
   } 
   catch (CMemoryException* pEx)
   {
      pEx->ReportError();
      pEx->Delete();
   }

>Also, what is all this business with THROW and CATCH etc, 
>instead of the C++ throw & catch? Is this just MFC shouting so we 
>notice what is going on :), or should I be using them for my exception 
>handling too?

Please read the documentation.  It explains that the THROW and CATCH
macros are there just for backward compatibiltiy. MFC had exception
handling before the C++ Committee was even a twinkle in ANSI's eye.
In current versions of MFC (like MFC 4.0, which you're using), the
macros translate _almost_ directly to the C++ keywords.  The
documentation explains how to convert the macros to C++ keywords,
if you'd like to do that.  'Course, you have to _read_ it, first.

.B ekiM
http://www.nwlink.com/~mikeblas/
I'm afraid I've become some sort of speed freak.
These words are my own. I do not speak on behalf of Microsoft.

-----From: Amir Shoval 

Paul Martinsen wrote:
> 
> Environment: VC++ 4.0, Win 95
> 
> Hello,
>   I was testing my error handling code last night & discovered what I
> would call an error in the documentation. In many cases the MFC help
> notes that a function could throw an exception, for example
> CArray::InsertAt throws exceptions when there is insufficient memory
> to insert the element. However, I discovered that it is actually a
> POINTER that is thrown, not a CMemoryException (for example) object,
> in otherwords the following code doesn't catch the error:
> 
> try
> { myArray.InsertAt(10,pNewObject);
> } catch (CMemoryException)
> { AfxMessageBox(IDS_NO_MORE_MEMORY);
> }
> 
> The catch line must read:
> catch (CMemoryException *)
Yes, This is *exactly* how it should read according to C++ language
rules (*not* MFC's). In fact, even a better one is:

	catch (CMemoryException *e)

so you can use the exception pointer in the catch block to gain 
information about the exception.

> to catch the exception thrown by InsertAt. I looked at the code that
> seems to be used for throwing these, eg AfxThrowMemoryException(),
> and it seems to use a pointer to a static object which, of course,
> doesn't need to be deleted. Does anybody know if this is always
> true, ie do I every have to delete the pointer that I get in the
> catch? Also, what is all this business with THROW and CATCH etc,
> instead of the C++ throw & catch? Is this just MFC shouting so we
> notice what is going on :), or should I be using them for my exception
> handling too?
> 
> Paul.

MFC once did not support c++ try & catch mechanism and the exception
handling was done using MFC's macros TRY, CATCH & THROW. MFC docs says
you better use the new supported c++ mechanism for compatability
reasons. You can read about it in any c++ language reference.

	Amir

--------------------------
Amir Shoval N.C.C. Israel
torin@netvision.net.il
--------------------------
-----From: SCS.007@mch.scn.de

>> Environment: VC++ 4.0, Win 95

>> to insert the element. However, I discovered that it is actually a 
>> POINTER that is thrown, not a CMemoryException (for example) object, 
>> in otherwords the following code doesn't catch the error:

>> try
>> { myArray.InsertAt(10,pNewObject);
>> } catch (CMemoryException)
>> { AfxMessageBox(IDS_NO_MORE_MEMORY);
>> }

>> The catch line must read:
>> catch (CMemoryException *)
>> to catch the exception thrown by InsertAt. I looked at the code that

Use TRY, CATCH, AND_CATCH, END_CATCH - It gives you an exception object.

>> catch? Also, what is all this business with THROW and CATCH etc, 
>> instead of the C++ throw & catch? Is this just MFC shouting so we 
>> notice what is going on :), or should I be using them for my exception 
>> handling too?
During the days of VC++ 1.5, 1.52, the C++ team of Microsoft had not 
supported exception handling machanism. Smart that the MFC team is, came up 
with the TRY-CATCH  mechanism - basically macros which provide that 
functionality to you. MSVC 4.0 completely supports the C++ specification. You 
should be thankful to them(MFC team). It does have some bugs though - for eg, 
in VC++ 1.52, CFile doesnt throw exceptions in some cases, even thoough it is 
documented. You can pardon them for such mistakes... .. sometimes.

Chandru.

Paul. 
-----From: jmitchell@cc-mail.derwent.co.uk

--IMA.Boundary.447099058
Content-Type: text/plain; charset=ISO-8859-1



Ash Williams -- ash@digitalworkshop.co.uk
Friday, December 20, 1996

I'm suprised you haven't found anything in the help.

Yes you must delete the caught exception, but use the 'Delete' member 
rather than the 'delete' operator.

Also TRY, THROW and CATCH are macros and were introduced before 
try, throw and catch were a part of the language. Unfortunately they're 
brain-dead as they rely on goto's, which of course means anything on 
the stack doesn't get cleaned up. Actually they probably evaluate to 
the language equivalent by now, but don't bother with them anyway just 
in case.

Ash





| Вернуться в корень Архива |