Connecting Tech Pros Worldwide Help | Site Map

opeator new question: again!

john sun
Guest
 
Posts: n/a
#1: Jul 22 '05
Here is snippet code.
class B contains class A and A1 as data member. when client code execute new
B(), B construtor throw exception, ...
C++ will call destrcutor of A and A1 seperately. This is very confusing.
Since A1 and A are also on heap. How C++ track dow these member? Thanks!

#include <stdio.h>
#include <memory>
using namespace std;

class O
{
public:
O(){};
~O(){};
}
;
class A1
{
O* o;
public :
A1()
{
o=new O();
printf("in A1 ctor\n");
}
~A1()
{
delete o;
printf("in A1 dtor\n");
};
};

class A
{
public :
A(){printf("in A ctor\n");};
~A(){printf("in A dtor\n");};
};
class B
{

auto_ptr<A> a;
A1 a1;
public:
B():a(new A)
{
throw 1;
}
~B(){printf("in B dtor\n");}
};


int main(int argc, char* argv[])
{
try{
B *b=new B();
}
catch(int)
{
printf("catch block\n");
}
return 0;
}


After running a1 and a destructor will be called. This confused me. Since b
is created in heap, and a and a1 is also on heap, how come exception can
call a1 and a's destructor.

Thanks for furthermore clarifying.

Best regards to all!



Andrey Tarasevich
Guest
 
Posts: n/a
#2: Jul 22 '05

re: opeator new question: again!


john sun wrote:[color=blue]
> Here is snippet code.
> class B contains class A and A1 as data member. when client code execute new
> B(), B construtor throw exception, ...
> C++ will call destrcutor of A and A1 seperately. This is very confusing.
> Since A1 and A are also on heap. How C++ track dow these member? Thanks!
>
> #include <stdio.h>
> #include <memory>
> using namespace std;
>
> class O
> {
> public:
> O(){};
> ~O(){};
> }
> ;
> class A1
> {
> O* o;
> public :
> A1()
> {
> o=new O();
> printf("in A1 ctor\n");
> }
> ~A1()
> {
> delete o;
> printf("in A1 dtor\n");
> };
> };
>
> class A
> {
> public :
> A(){printf("in A ctor\n");};
> ~A(){printf("in A dtor\n");};
> };
> class B
> {
>
> auto_ptr<A> a;
> A1 a1;
> public:
> B():a(new A)
> {
> throw 1;
> }
> ~B(){printf("in B dtor\n");}
> };
>
>
> int main(int argc, char* argv[])
> {
> try{
> B *b=new B();
> }
> catch(int)
> {
> printf("catch block\n");
> }
> return 0;
> }
>
>
> After running a1 and a destructor will be called. This confused me. Since b
> is created in heap, and a and a1 is also on heap, how come exception can
> call a1 and a's destructor.
> ...[/color]

For 'a1' it doesn't really matter whether it is "on heap" or on
something else. 'a1' is a member subobject of class 'B'. In other words,
'a' is not a standalone object, it is an integral part of 'B' object, it
is embedded in 'B' object. This immediately means that its destructor
will be called in this situation. Destructors for _all_ immediate
subobjects of class 'B' will be called if 'B::B()' throws an exception
the way it is thrown in your code.

This also applies to 'a', which is an 'auto_ptr' subobject of class 'B'.
'a's destructor ('auto_ptr::~auto_ptr') is called, which in turn
'delete's the 'A' object dynamically allocated in the constructor
initialization list.

--
Best regards,
Andrey Tarasevich

Peter Koch Larsen
Guest
 
Posts: n/a
#3: Jul 22 '05

re: opeator new question: again!



"john sun" <johnsun@sbcglobal.net> skrev i en meddelelse
news:VFjNb.56966$p03.5127@newssvr31.news.prodigy.c om...[color=blue]
> Here is snippet code.
> class B contains class A and A1 as data member. when client code execute[/color]
new[color=blue]
> B(), B construtor throw exception, ...
> C++ will call destrcutor of A and A1 seperately. This is very confusing.
> Since A1 and A are also on heap. How C++ track dow these member? Thanks!
>
> #include <stdio.h>
> #include <memory>
> using namespace std;
>
> class O
> {
> public:
> O(){};
> ~O(){};
> }
> ;
> class A1
> {
> O* o;
> public :
> A1()
> {
> o=new O();
> printf("in A1 ctor\n");
> }
> ~A1()
> {
> delete o;
> printf("in A1 dtor\n");
> };
> };
>
> class A
> {
> public :
> A(){printf("in A ctor\n");};
> ~A(){printf("in A dtor\n");};
> };
> class B
> {
>
> auto_ptr<A> a;
> A1 a1;
> public:
> B():a(new A)
> {
> throw 1;
> }
> ~B(){printf("in B dtor\n");}
> };
>
>
> int main(int argc, char* argv[])
> {
> try{
> B *b=new B();
> }
> catch(int)
> {
> printf("catch block\n");
> }
> return 0;
> }
>
>
> After running a1 and a destructor will be called. This confused me. Since[/color]
b[color=blue]
> is created in heap, and a and a1 is also on heap, how come exception can
> call a1 and a's destructor.
>
> Thanks for furthermore clarifying.
>
> Best regards to all!
>
>
>[/color]
When an exception in a constructor causes an object not to be created, all
members that were constructed will be destroyed automatically. Have a look
at B's constructor:

B():a(new A)
{
throw 1;
}

Since all members not explicitly constructed are default-constructed, this
code really corresponds to

B():a(new A),a1()
{
throw 1;
}

so both a and a1 are constructed at entry to the constructor body.


/Peter


Closed Thread