| View previous topic :: View next topic |
| Author |
Message |
Richard Guest
|
Posted: Thu May 03, 2007 6:07 am Post subject: Form Handling |
|
|
The code within the "try" segment seems to work just fine
so long as the correct pass word is entered into the form
on the 1st attempt. (the form appears and then goes away)
However, if it is necessary to return to this code due to
cycling for a correct PW after invalid entry, the exception
"Abstract Error" is thrown at the "new" statement.
I note that the usual "[]" along with the "delete" are not
used below, and indeed, a test with them caused an error
immediately.
What is a "cast-expression"?
// NOTE: "fs_" ---> "File Scope"
try{
PW_InputForm = new TPW_InputForm(this);
fs_ModalFormResults = PW_InputForm->ShowModal();
delete PW_InputForm;
return;
}
catch(const Exception& E)
{
String sTypeOfException__ = E.Message;
String sMsg = "Trapped exception message = ";
sMsg += sTypeOfException__ + sCR;
int Btns = MB_ICONINFORMATION;
FillcCaption_MACRO(Bad delete [])
Application->MessageBox(sMsg.c_str(), pCaption, Btns);
}
Richard |
|
| Back to top |
|
 |
Leo Siefert Guest
|
Posted: Thu May 03, 2007 5:02 pm Post subject: Re: Form Handling |
|
|
Richard wrote:
| Quote: | I note that the usual "[]" along with the "delete" are not
used below, and indeed, a test with them caused an error
immediately.
|
That's lucky - often does not cause an immediate error. Always use
delete with new and delete[] with new[]. delete[] and new[] are for
arrays.
| Quote: | What is a "cast-expression"?
|
Used to convert to a different type: static_cast<>(),
dynamic_cast<>(), reinterpret_cast<>(), static_cast<>(). Also
deprecated c style cast, but that is best avoided.
| Quote: | PW_InputForm = new TPW_InputForm(this);
fs_ModalFormResults = PW_InputForm->ShowModal();
delete PW_InputForm;
|
Why not avoid the dynamic allocation and provide better exception
safety:
fs_ModalFormResults = TPW_InputForm(this).ShowModal();
| Quote: | catch(const Exception& E)
|
What are you trying to catch here? I hope this is not to catch an
invalid password entry - not a good idea to use exceptions for
expected conditions. note that if there is an exception thrown by the
form in your original code the delete never happens. If you do not use
new, then C++ will guarantee cleanup.
I suspect that your actual problem may be from using the IDE-generated
global variable for your form (PW_InputForm) - note that the code I
show does not even use a variable name for the form. Best rule of
thumb: do not use any global variables. Minimal requirement: do not
use global form names for any forms that may be created more than
once. If you need a variable name for such a form use a local variable
like:
TPW_InputForm inputform(this);
fs_ModalFormResults = inputform.ShowModal();
xyz = inputform.getXYZ();
....
- Leo |
|
| Back to top |
|
 |
Clayton Arends Guest
|
Posted: Thu May 03, 2007 10:29 pm Post subject: Re: Form Handling |
|
|
| Quote: | Why not avoid the dynamic allocation and provide better exception
safety:
fs_ModalFormResults = TPW_InputForm(this).ShowModal();
|
VCL classes (those descending from TObject) must be dynamically allocated.
- Clayton |
|
| Back to top |
|
 |
Clayton Arends Guest
|
Posted: Thu May 03, 2007 10:39 pm Post subject: Re: Form Handling |
|
|
| Quote: | try{
PW_InputForm = new TPW_InputForm(this);
|
General notes.
1) The allocation should not be in the try{} rather it should preceed it.
2) Just like Leo said you should use a local variable rather than a global
since the scope of this form's use is local to the method.
3) Instead of deleting the form directly you should use a smart pointer like
std::auto_ptr in the STL. This provides exception-safe object deletion. To
use this class you need to #include <memory>.
TPW_InputForm* form = new TPW_InputForm(this);
std::auto_ptr<TPW_InputForm> auto_form(form);
try
{
fs_ModalFormResults = form->ShowModal();
// no need for this --> return;
}
catch (const Exception& E)
{
// ...
}
As for the exception handler you need to show what FillcCaption_MACRO is in
order for anyone to help figure out what's going wrong there.
- Clayton |
|
| Back to top |
|
 |
Old Wolf Guest
|
Posted: Fri May 04, 2007 3:28 am Post subject: Re: Form Handling |
|
|
"Clayton Arends" <nospam_claytonarends (AT) hotmail (DOT) com> wrote:
| Quote: | General notes.
1) The allocation should not be in the try{} rather it should preceed it.
|
What if it throws an exception during construction ?? The
allocation should be inside the try-block.
try
{
std::auto_ptr<TPW_InputForm> form
( new TPW_InputForm(this) );
fs_ModalFormResults = form->ShowModal();
}
catch (Exception& E)
{
// ...
}
I think you also need a catch( std::exception & ) to catch the error when memory allocation fails , not sure if Borland converts that error to a VCL Exception or not. |
|
| Back to top |
|
 |
Remy Lebeau (TeamB) Guest
|
Posted: Fri May 04, 2007 5:10 am Post subject: Re: Form Handling |
|
|
"Leo Siefert" <lIHATESPAMsiefert (AT) senate (DOT) michigan.gov> wrote in message
news:k7ij335rs8vkka7h7rm26gf0fhc6j340q6 (AT) 4ax (DOT) com...
| Quote: | Why not avoid the dynamic allocation and provide better
exception safety:
fs_ModalFormResults = TPW_InputForm(this).ShowModal();
|
Because you can't do that with VCL classes.
| Quote: | note that if there is an exception thrown by the form in your
original code the delete never happens.
|
Yes, it will be freed, just not immediately. Richard assigned an
Owner to the form, so it will be freed when the Owner is freed later
on.
Gambit |
|
| Back to top |
|
 |
Remy Lebeau (TeamB) Guest
|
Posted: Fri May 04, 2007 5:12 am Post subject: Re: Form Handling |
|
|
"Clayton Arends" <nospam_claytonarends (AT) hotmail (DOT) com> wrote in message
news:463a1e42 (AT) newsgroups (DOT) borland.com...
| Quote: | The allocation should not be in the try{} rather it should preceed
it. |
That depends on what the form's constructor is actually doing. It is
valid, albeit not very common, to sometimes catch construction errors
and handle them manually.
Gambit |
|
| Back to top |
|
 |
Clayton Arends Guest
|
Posted: Fri May 04, 2007 8:10 am Post subject: Re: Form Handling |
|
|
| Quote: | What if it throws an exception during construction ??
|
That would be a condition that gets handled higher up, not by the exception
handler code shown by the OP. The point I was trying to make is that it is
a common mistake that programmers do to put the allocation inside of the try
block. In Delphi it is more common to see this kind of mistake:
try
Form := TMyForm.Create(self);
Form.ShowModal;
finally
Form.Free; // tsk tsk
end;
// or sometimes
try
Form := TMyForm.Create(self);
Form.ShowModal;
catch E : Exception
ShowMessage(Form.ErrorIndicator); // << bad bad bad
end;
However, if the construction of the form might throw an exception that the
user will want to handle then this would be the code to use:
try
{
form = new TMyForm(this);
std::auto_ptr<TMyForm> auto_form(form);
try
{
form->ShowModal();
}
catch (Exception const& E)
{
// OP exception handler
}
}
catch (Exception const& E)
{
// form allocation error handler
}
I prefer to let higher up code handle allocation exceptions. Most classes I
write never throw unless it is unexpected behavior such as out of memory
errors.
- Clayton |
|
| Back to top |
|
 |
Clayton Arends Guest
|
Posted: Fri May 04, 2007 8:10 am Post subject: Re: Form Handling |
|
|
| Quote: | That depends on what the form's constructor is actually doing. It is
valid, albeit not very common, to sometimes catch construction errors
and handle them manually.
|
Agreed.
- Clayton |
|
| Back to top |
|
 |
Leo Siefert Guest
|
Posted: Fri May 04, 2007 7:23 pm Post subject: Re: Form Handling |
|
|
Remy Lebeau wrote:
| Quote: | fs_ModalFormResults = TPW_InputForm(this).ShowModal();
Because you can't do that with VCL classes.
|
Ever tried it? Works for me and CodeGuard doesn't complain. I use this
type of code extensively.
| Quote: | Yes, it will be freed, just not immediately.
|
That was my point. His code can now assign another instance of the
form to the same global pointer when the user retries the password
entry. If this code is in the main form than VCL cleanup will not
happen until the app closes down.
- Leo |
|
| Back to top |
|
 |
Remy Lebeau (TeamB) Guest
|
Posted: Fri May 04, 2007 10:13 pm Post subject: Re: Form Handling |
|
|
"Leo Siefert" <lIHATESPAMsiefert (AT) senate (DOT) michigan.gov> wrote in message
news:35gm33da3k7nfus3jnleaddr43387q948h (AT) 4ax (DOT) com...
Yes, actually I have, and it caused corruption. TObject-based objects
*MUST* be created on the heap at all times. That is a requirement of
the RTL. I once put a TForm onto the stack instead of the heap, which
the compiler is not supposed to allow but it did, and had runtime
crashes because of it.
| Quote: | Works for me and CodeGuard doesn't complain. I use this
type of code extensively.
|
Not for TObject-based classes, you can't. For anything else, you can.
TObject is unique in its requirements because of the Delphi-C++
compatibilty layer.
Gambit |
|
| Back to top |
|
 |
Duane Hebert Guest
|
Posted: Fri May 04, 2007 11:44 pm Post subject: Re: Form Handling |
|
|
"Leo Siefert" <lIHATESPAMsiefert (AT) senate (DOT) michigan.gov> wrote in message
news:35gm33da3k7nfus3jnleaddr43387q948h (AT) 4ax (DOT) com...
| Quote: | Remy Lebeau wrote:
fs_ModalFormResults = TPW_InputForm(this).ShowModal();
Because you can't do that with VCL classes.
Ever tried it? Works for me and CodeGuard doesn't complain. I use this
type of code extensively.
|
Which version of Borland are you using?
With BCB 4,5 and 6 it wouldn't compile like that.
Even if it did compile, it's documented that VCL
classes MUST be created on the heap.
You should also know that CodeGuard doesn't readily
detect leaks in VCL objects either so I would not use that
as a benchmark. |
|
| Back to top |
|
 |
vavan Guest
|
Posted: Mon May 07, 2007 1:47 pm Post subject: Re: Form Handling |
|
|
On Fri, 4 May 2007 10:13:29 -0700, "Remy Lebeau \(TeamB\)"
<no.spam (AT) no (DOT) spam.com> wrote:
| Quote: | Yes, actually I have, and it caused corruption. TObject-based objects
*MUST* be created on the heap at all times. That is a requirement of
the RTL. I once put a TForm onto the stack instead of the heap, which
the compiler is not supposed to allow but it did, and had runtime
crashes because of it.
|
the compiler usually barks (E2459 VCL style classes must be
constructed using operator new) in such cases which prevents from such
mistakes
unfortunately there is some bug in compiler so it sometimes generates
the very same compile-time error when it actually shouldn't. I for
example got it when tried to pass reference to VCL-based object to
some template code (though usually it works), looks like it
inadvertently decided to create temporary copy of that object :(
--
Vladimir Ulchenko aka vavan |
|
| Back to top |
|
 |
Leo Siefert Guest
|
Posted: Mon May 07, 2007 5:50 pm Post subject: Re: Form Handling |
|
|
Duane Hebert wrote:
| Quote: | Which version of Borland are you using?
|
Tested in both BCB6 and BDS2006 - I no longer have BCB5 installed, but
I'm pretty sure some of my code using this has been around at least
that long.
As long as I only use the VCL object as a temporary the compiler does
not complain and the code works - even for forms that call other forms
and contain rather extensive code.
- Leo |
|
| Back to top |
|
 |
Leo Siefert Guest
|
Posted: Mon May 07, 2007 5:59 pm Post subject: Re: Form Handling |
|
|
vavan wrote:
| Quote: | the compiler usually barks (E2459 VCL style
classes must be constructed using operator new)
in such cases which prevents from such mistakes
|
Yes, and I have always just relied on that to catch this. In cases
where the compiler does not complain, I assume the code is ok. Maybe I
need to file a QC report on this if there is not already one.
- Leo |
|
| Back to top |
|
 |
|