Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C++ > More effective C++

Reply
Thread Tools

More effective C++

 
 
vikram_p_nayak@yahoo.com
Guest
Posts: n/a
 
      06-15-2006
I was just going through this book by Scott Meyers and did not fully
follow item 10.
Basically he says the constructor should catch all exceptions, do any
cleanups necessary and then throw. This is because otherwise the member
objects already created can not be destroyed from outside since the
container object itself is not fully created.

Look at this - (myclass contains objects of class1 and class2)
Class myclass {
class1 m_class1;
class2 m_class2;
public:
myclass(int c1, int c2):m_class1(c1), m_class2(c2) {}
}

Assume both class1 and class2 have constructors which take int
parameters.
so m_class1 gets initialized first and then m_class2. If the contructor
of class2 throws an exception, even after its own cleanup, how would it
help? m_class1 is already contructed. How is it destroyed?

I actually tried this on VC++ 6 compiler and it seems to work. As in ,
m_class1's destructor indeed gets called! I think class1 and class2
initializations are independently happening and we can not cleanup one
because of an exception in the other.

Please let me know if I am missing something here. How does the
compiled code know that m_class1 is contructed and it needs to be
destroyed whereas it passes the exception from m_class2 as is.

 
Reply With Quote
 
 
 
 
Pete Becker
Guest
Posts: n/a
 
      06-15-2006
http://www.velocityreviews.com/forums/(E-Mail Removed) wrote:
>
> Assume both class1 and class2 have constructors which take int
> parameters.
> so m_class1 gets initialized first and then m_class2. If the contructor
> of class2 throws an exception, even after its own cleanup, how would it
> help? m_class1 is already contructed. How is it destroyed?
>


The compiler generates code that destroys it. The cleanup you need to do
in response to an exception in a constructor is for things that don't
have appropriate destructors.

--

Pete Becker
Roundhouse Consulting, Ltd.
 
Reply With Quote
 
 
 
 
vikram_p_nayak@yahoo.com
Guest
Posts: n/a
 
      06-15-2006
> The cleanup you need to do
> in response to an exception in a constructor is for things that don't
> have appropriate destructors.


Thanks for the response. But I will have to disagree a bit. Infact in
the example he has given in the book the cleanup code has
delete theImage;
etc where theImage is an object with a welldefined dtor.

--Vikram

 
Reply With Quote
 
vikram_p_nayak@yahoo.com
Guest
Posts: n/a
 
      06-15-2006
> The cleanup you need to do
> in response to an exception in a constructor is for things that don't
> have appropriate destructors.


Thanks for the response. But I will have to disagree a bit. Infact in
the example he has given in the book the cleanup code has
delete theImage;
etc where theImage is an object with a welldefined dtor.

--Vikram

 
Reply With Quote
 
Gernot Bauer
Guest
Posts: n/a
 
      06-15-2006
(E-Mail Removed) schrieb:
>> The cleanup you need to do
>> in response to an exception in a constructor is for things that don't
>> have appropriate destructors.

>
> Thanks for the response. But I will have to disagree a bit. Infact in
> the example he has given in the book the cleanup code has
> delete theImage;
> etc where theImage is an object with a welldefined dtor.


The example in the book dynamically allocates memory with "new". The
code snippet you have posted doesn't. Note the difference.
Therefore, you need to delete theImage explicitly (at this point, the
dtor of theImage will be called). When using new, you have the
responsibility clear the memory on your own (but you could use something
as boost::shared_ptr and give the responsibility of deletion to this
class).

> --Vikram


hth,
Gernot
 
Reply With Quote
 
Richard Herring
Guest
Posts: n/a
 
      06-15-2006
In message <(E-Mail Removed). com>,
(E-Mail Removed) writes
>> The cleanup you need to do
>> in response to an exception in a constructor is for things that don't
>> have appropriate destructors.

>
>Thanks for the response. But I will have to disagree a bit. Infact in
>the example he has given in the book the cleanup code has
>delete theImage;
>etc where theImage is an object with a welldefined dtor.


Nope. theImage is a *pointer* to such an object. Pointers don't have
destructors, so _you_ have to arrange that the object it points to gets
destroyed, by calling delete.


--
Richard Herring
 
Reply With Quote
 
vikram_p_nayak@yahoo.com
Guest
Posts: n/a
 
      06-15-2006
> The example in the book dynamically allocates memory with "new". The
> code snippet you have posted doesn't. Note the difference.
> Therefore, you need to delete theImage explicitly (at this point, the
> dtor of theImage will be called). When using new, you have the
> responsibility clear the memory on your own (but you could use something
> as boost::shared_ptr and give the responsibility of deletion to this
> class).


Thanks Gernot. Yes, you are right about the example in the book. I was
trying to demonstrate my confusion using objects rather than pointers
because the book specifically says pointers better have a try/catch
blocks for initializations, either in constructor or in a private
member function. Please have a look at the initImage/initAudioImage
methods on page 73 (atleast for the version of the book I have).

In short, I am fine with all the examples that the book has. But I had
a question regarding the whole concept when we have member
initialization lists. How does the code know that m_class1 is already
constructed and should be destroyed? The destructor of the container
object does not get called since it has thrown an exception. So how it
figure out the member objects that are fully created?

Thanks,
Vikram

 
Reply With Quote
 
Howard
Guest
Posts: n/a
 
      06-15-2006

<(E-Mail Removed)> wrote in message
news:(E-Mail Removed) oups.com...
>> The example in the book dynamically allocates memory with "new". The
>> code snippet you have posted doesn't. Note the difference.
>> Therefore, you need to delete theImage explicitly (at this point, the
>> dtor of theImage will be called). When using new, you have the
>> responsibility clear the memory on your own (but you could use something
>> as boost::shared_ptr and give the responsibility of deletion to this
>> class).

>
> Thanks Gernot. Yes, you are right about the example in the book. I was
> trying to demonstrate my confusion using objects rather than pointers
> because the book specifically says pointers better have a try/catch
> blocks for initializations, either in constructor or in a private
> member function. Please have a look at the initImage/initAudioImage
> methods on page 73 (atleast for the version of the book I have).
>
> In short, I am fine with all the examples that the book has. But I had
> a question regarding the whole concept when we have member
> initialization lists. How does the code know that m_class1 is already
> constructed and should be destroyed? The destructor of the container
> object does not get called since it has thrown an exception. So how it
> figure out the member objects that are fully created?
>


Hi Vikram,

an initialization list is not the same as code in the constructor body.
Those member object initializers you show [:m_class1(c1), m_class2(c2)] are
not normal function calls. They're more like instructions to the compiler
as to _how_ the member objects should be initialized at construction time.
So the normal rules still apply for construction and destruction (and thus
the automatic calling of contructors and destructors).

During construction, the members are constructed for you, in the order
they are declared in the class (which need not be the same as the order of
your initialization list, by the way). When the class is destroyed, the
members are deconstructed in reverse order, and then the class object itself
is destroyed. So all destructors get called automatically.

It's only when you do dynamic allocations in your constructor (e.g.,
using new) that you need to worry about making sure you call delete in the
event of a failure in the constructor.

-Howard






 
Reply With Quote
 
Howard
Guest
Posts: n/a
 
      06-15-2006

For me, the most annoying aspects of C++ are:

- It's hard to spell.
- It's not Delphi (or Java, or VB).
- There's always that terrible nagging fear that, should I invoke Undefined
Behavior (TM), my hard drive might catch fire, my email system send nasty
messages to my boss, or I could accidently launch a Titan III missile at
China, starting World War 3.

Oh yeah, there's that annoying part about getting paid too much, too...

-Howard


 
Reply With Quote
 
Howard
Guest
Posts: n/a
 
      06-15-2006

"Howard" <(E-Mail Removed)> wrote in message news:6xfkg.28520

oops, wrong thread... <Cancel!><Cancel!!><Cancel!!!>...arrgh!

(Now ask me about the most annoying things about Outlook Express...)


 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Making code more efficient and effective cokofreedom@gmail.com Python 3 06-26-2008 03:53 PM
More Effective C++ barcaroller C++ 4 04-13-2007 06:00 PM
printing or copying more cost effective brazen NZ Computing 8 01-13-2006 06:28 PM
When is std::list more effective than the other containers? Josh Mcfarlane C++ 44 12-16-2005 04:40 PM
more effective c++ item 31 cfchou@gmail.com C++ 4 09-27-2005 09:15 AM



Advertisments