Prev: Deriving from a class derived from a CDialog
Next: How to show underlined menu shortcut letters by default for a contextmenu ?
From: Joseph M. Newcomer on 22 Jun 2010 19:51 Note that this could be handled as BOOL TryParse(...args...) { try { Parse(...); return TRUE; } catch(..whatever..) { return FALSE; } } It ain't rocket science. And it isn't clear to me how handling the exception results in "bad code". oje On Wed, 23 Jun 2010 00:18:49 +0200, Giovanni Dicanio <giovanniDOTdicanio(a)REMOVEMEgmail.com> wrote: >On 22/06/2010 23:06, David Ching wrote: > >> Exceptions are meant for rarely occurring ERROR conditions (you >> know, 'exceptional' conditions!), not normal control flow.I once saw a >> switch statement rewritten as a bunch of thrown exceptions, not a pretty >> sight. > >I do agree with you David. > >The Parse vs. TryParse case of .NET comes in my mind: the earlier >versions of the framework had the Parse method, which threw exceptions >in case of parsing error. In later versions (since 2.0?) they introduced >TryParse, which just returned an error code. > >Surrounding Parse calls with try/catch blocks produced bad code; instead >a simple if-check of TryParse return code is much better, IMHO. > >Giovanni Joseph M. Newcomer [MVP] email: newcomer(a)flounder.com Web: http://www.flounder.com MVP Tips: http://www.flounder.com/mvp_tips.htm
From: Joseph M. Newcomer on 22 Jun 2010 19:54 See below... On Tue, 22 Jun 2010 18:35:05 -0400, "RB" <NoMail(a)NoSpam> wrote: >> *** >> But the point here is that it *has* called the virtual method >> ReportSaveLoadException. and it return FALSE from OnOpenDocument. >> ............ >> Because this is a virtual method, you could override it and if calling the parent >> returned NULL, you could do something useful such as setting the filename to >> empty. I think this code actually is incorrect, but you can create your own >> subclass and do whatever you want. >------------------------------------------ >Hey Joe, this is getting a bit confusing for me. Why would I want to create my >own subclass to set the filename to empty when the below framwork code >(that I previously posted ) sets the filename to "untitled" for me which keeps >me from inadvertly saving and overwriting any previous persistence ? ? >>> if (!pDocument->OnOpenDocument(lpszPathName)) **** If throwing the exception works, then the answer is, you wouldn't want to do this. But I thought you said that it didn't solve the problem. joe **** >>> { >>> ........ >>> else >>> { >>> SetDefaultTitle(pDocument); >>>// RB the above sets the filename to "untitled" >>>........... Joseph M. Newcomer [MVP] email: newcomer(a)flounder.com Web: http://www.flounder.com MVP Tips: http://www.flounder.com/mvp_tips.htm
From: RB on 22 Jun 2010 20:14 > **** > If throwing the exception works, then the answer is, you wouldn't want to do this. Oh ok, thanks. > But I thought you said that it didn't solve the problem. > **** No, I said that when I interrupted the "end of file" exception by inserting a catch ( CException, e ) ( which I'm sure was a mistake now) then I lost the mfc cleanup. But if mfc catches it on it's own without any try / catch on my part and does all the cleanup and setting the filename to "untitled" ( found all of this out by stepping thru the framework for each scenario) And to the dilemma of my file id I found that if I threw the AfxThrowArchiveException in my if loop (code below) that it gave me all the same cleanup and reset code said above. ar >> FID_Read;; // DWORD FID_Read; if (FID_Read != FileID) // const DWORD FileID; { // FileID mismatch AfxThrowArchiveException(CArchiveException::badIndex, NULL ); //Invalid file format } ar >> VerData.Ver >> VerData.CpyRt >> VerData.Corp; ar.SerializeClass(RUNTIME_CLASS(CMapStringToString)); ExpMap1.Serialize(ar); /// Also note I put the file id in a const as you told me.
From: RB on 22 Jun 2010 20:36 > **** > As already pointed out, doing a throw directly inside a try is probably not good style. > Now if you called another function that called a function that called a function that did > a throw, that makes more sense. Oh ok, so like if I , // declared in CMyDoc.h const DWORD FileID; // and in my doc ctor CMyDoc::CMyDoc( ) : FileID(FILE_ID) { VerData.Ver.Format( _T("Version %d.%d.%d.%d"), VERMAJ, VERMIN, VERFIX, BUILDNUM ); VerData.CpyRt = _T(CPY_RT_YR_STR_LITERAL); } // and in my doc serialize do, try { DWORD FID_Read; ar >> FID_Read;; Check_ID_Match ( FID_Read ); ......... .......... /////////////////////////////////////////////////////////////// void CMyDocClass::Check_ID_Match ( DWORD& Read ) { if ( Read != FileID) { // FileID mismatch throw new CWhateverDoesTheJob( ByReadingDocsAndOrSteppingThru); } }
From: David Ching on 22 Jun 2010 22:10
"Joseph M. Newcomer" <newcomer(a)flounder.com> wrote in message news:d0j2261qbnp0hepna91efqiiesg126u0st(a)4ax.com... > Note that this could be handled as > > BOOL TryParse(...args...) > { > try > { > Parse(...); > return TRUE; > } > catch(..whatever..) > { > return FALSE; > } > } > > It ain't rocket science. And it isn't clear to me how handling the > exception results in > "bad code". > oje > This implementation of TryParse() doesn't solve the problem we were talking about. The problem is that if an exception is thrown for the common occurrence of malformed args, the result is it is SLOWNESS! This implementation would fix this problem: BOOL TryParse(...args...) { if (!IsValid(args)) return FALSE; Parse(...); // Parse() will not throw because args are valid return TRUE; } -- David |