opeator new question: again!

J

john sun

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!
 
A

Andrey Tarasevich

john said:
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.
...

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.
 
P

Peter Koch Larsen

john sun said:
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!
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
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
474,159
Messages
2,570,879
Members
47,414
Latest member
GayleWedel

Latest Threads

Top