Having the following code:
#include <iostream>
struct A
{
int x;
A(){}
~A(){std::cout <<"~A("<<x<<")\n";}
};
struct B: public A
{
};
void f(A a)
{
a.x = 2;
}
void main()
{
B b;
std::cout <<"----------\n";
b.x = 1;
f(b);
b.x = 3;
std::cout <<"----------\n";
}
In this case the output is following:
----------
~A(2)
~A(1)
----------
~A(3)
The same code but virtual function is added to parent class:
#include <iostream>
struct A
{
int x;
A(){}
~A(){std::cout <<"~A("<<x<<")\n";}
virtual void ff() {}
A(A& ca): x(ca.x){}
};
struct B: public A
{
};
void f(A a)
{
a.x = 2;
}
void main()
{
B b;
std::cout <<"----------\n";
b.x = 1;
f(b);
b.x = 3;
std::cout <<"----------\n";
}
In this case we have the following output:
----------
~A(2)
----------
~A(3)
EDIT:
Compiler is: MSVCPP 10
The questions are the following:
- Why we have double copying in the first case?
- Why we have only one copying in the second case?
- The 1st case: why does compiler not optimizes the 1st case (by reducing copy operations quantity)?
-
Does the following code:
void f(int); //... double d; f(d);
also make double-copying?
The output on gcc 4.3.4 for both cases is:
Example 1
Example 2
This output can be explained as:
When you call
f(b);an copy of the object of typeBis created since it is pass by value.But there is Object slicing, since the function parameter takes on object of type
A. Thus the object in the function now is of the typeAand it gets destroyed while returning from the function resulting in call output~A(2).The following two traces are from the destruction of the object
bwhich is created in themain(), Since it is of the type ofBdestructors for base classAand derived classBboth are called for it.I am not sure if I missed out any obvious optimization that gcc might be performing in this case but for me the outputs look pretty much as expected.