By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
459,292 Members | 1,354 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 459,292 IT Pros & Developers. It's quick & easy.

i've got strange destructor

P: n/a
Hey,

Here's a sample code you can easily guess the result. <result 1>

#include <iostream>
using namespace std;
class AA
{
public:
AA() { cout<<"AA();"<<endl; }
AA(const AA&) { cout<<"AA(const AA&);"<<endl; }
~AA() { cout<<"~AA();"<<endl; }
};

void Foo(AA aa)
{
}

int main(int, char**)
{
Foo(AA());
}

BUT, I found strange result when I removed copy constructor of AA
class. <result 2>

(vs.net 2003 - ms c/c++ compiler 13.10.3077)

<result 1>
AA();
~AA();
<result 2>
AA();
~AA();
~AA();
Can anyone explain me the reason why the destructor called twice when I
removed copy constructor ?

Sep 26 '05 #1
Share this Question
Share on Google+
4 Replies


P: n/a
al******@gmail.com wrote:
Hey,

Here's a sample code you can easily guess the result. <result 1>

#include <iostream>
using namespace std;
class AA
{
public:
AA() { cout<<"AA();"<<endl; }
AA(const AA&) { cout<<"AA(const AA&);"<<endl; }
~AA() { cout<<"~AA();"<<endl; }
};

void Foo(AA aa)
{
}

int main(int, char**)
{
Foo(AA());
}

BUT, I found strange result when I removed copy constructor of AA
class. <result 2>

(vs.net 2003 - ms c/c++ compiler 13.10.3077)

<result 1>
AA();
~AA();
<result 2>
AA();
~AA();
~AA();
Can anyone explain me the reason why the destructor called twice when I
removed copy constructor ?


Your example is odd, but perfectly legal. In your code you create a
temporary AA object with the default constructor and then create the
parameter aa by copy constructing the temporary. In <result 2> you see
this happen, the first destructor call is for the aa parameter the
second for the temporary. So two objects are created and two objects are
destroyed but you don't see the copy constructor call because the
compiler generated copy constructor doesn't print anything.

The compiler is allowed to optimise away the temporary use the default
constructor directly on parameter aa. It is allowed to do this even if
the copy constructor has a side effect (moral is, don't put anything in
a copy constructor that you don't mind being optimised away). So you can
have just one object created and one object destroyed and this is what
you see in <result 1>.

For me the odd part is that you only see this optimisation when you have
defined a copy constructor, you don't see it when you use the compiler
generated copy constructor. I would have thought it would be more likely
the other way around.

So odd, but legal.

john
Sep 26 '05 #2

P: n/a
So if I didn't want the optimisation to take place, and I did want the
call to void Foo(AA aa) to have the copy ctor called for aa, then how
would I do that? Is it simply a case of using aa in Foo or is there
more to that?

G

Sep 26 '05 #3

P: n/a
"Gr*****@nospam.com" wrote:

So if I didn't want the optimisation to take place, and I did want the
call to void Foo(AA aa) to have the copy ctor called for aa, then how
would I do that? Is it simply a case of using aa in Foo or is there
more to that?


There is more to it.
You need to tell your compiler to not do that optimization.
Depending on your compiler this might be possible or it
might not be possible.

Moral of story: Write your copy constructor in a way such that
it doesn't matter if it is optimized away. As John Harris
already said.
--
Karl Heinz Buchegger
kb******@gascad.at
Sep 26 '05 #4

P: n/a
Gr*****@nospam.com wrote:
So if I didn't want the optimisation to take place, and I did want the
call to void Foo(AA aa) to have the copy ctor called for aa, then how
would I do that? Is it simply a case of using aa in Foo or is there
more to that?

G


If you are willing to change your code slightly

void Foo(const AA& aa)
{
...
}

Using a reference means no copy constructor will be called.

john
Sep 26 '05 #5

This discussion thread is closed

Replies have been disabled for this discussion.