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

object slicing

P: n/a
Hi Everyone,

I was working around object slicing (pass by value) and was
wondering how it is specified in the standard,

class A
{
};

class B: public A
{
};

void fun(A obj)
{
}

int main()
{
B obj;
fun(obj); // obj is sliced into type of A, but how
exactly does it happen?
}

I noticed that the copy constructor of A is invoked and "thinking in c+
+" claims that to be essential for updating the vptr (if present) with
the proper VTABLE. [this is not in the above case]

Thanks in advance!!!
Dec 12 '07 #1
Share this Question
Share on Google+
2 Replies


P: n/a
Rahul wrote:
I was working around object slicing (pass by value) and was
wondering how it is specified in the standard,
It's not, really. The standard says that the object of the
derived type is converted into an object of the base type,
but does not say how the code does that. To specify it would
be to impose undue limitations on what the compiler can do.

In your case, however, it's a temporary of type 'A' that is
created. The creation of the temporary is done by copy-
constructing.
>
class A
{
};

class B: public A
{
};

void fun(A obj)
{
}

int main()
{
B obj;
fun(obj); // obj is sliced into type of A, but how
exactly does it happen?
The compiler constructs a temporary of type 'A' from the 'A' part
of the 'obj' (using the appropriate copy constructor). Any 'B'
obejct contains the 'A' part, and then some other stuff that makes
it different from an 'A' object. The other stuff is ignored during
copying.
}

I noticed that the copy constructor of A is invoked and "thinking in
c+ +" claims that to be essential for updating the vptr (if present)
with the proper VTABLE. [this is not in the above case]
The copy constructor invocation is essential for the process. But
the vtbl is not the reason. The object created by the slicing
process has to be changeable (inside your 'fun' function), and
should not cause any changes in the originating 'obj'. That's
why a different object (a temporary) is constructed.

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask
Dec 12 '07 #2

P: n/a
On Dec 12, 7:24 pm, "Victor Bazarov" <v.Abaza...@comAcast.netwrote:
Rahul wrote:
I was working around object slicing (pass by value) and was
wondering how it is specified in the standard,
It's not, really. The standard says that the object of the
derived type is converted into an object of the base type,
but does not say how the code does that. To specify it would
be to impose undue limitations on what the compiler can do.
Well, the standard does say a little bit more. For example, any
time an object is created, a constructor is called. And
overload resolution is applied as usual.
In your case, however, it's a temporary of type 'A' that is
created. The creation of the temporary is done by copy-
constructing.
That's the usual case.
class A
{
};
class B: public A
{
};
void fun(A obj)
{
}
If A had a constructor A::A( B const& ), in addition to the copy
constructor, then this constructor would be used, instead of the
copy constructor. Similarly, if B had a user defined conversion
to A, that would be used. (I think---but the rules here are
very subtle.)

As far as the standard is concerned, there is no such thing as
"slicing". You're passing an object of type B, and you need an
object of type A. The compiler does the usual overload
resolution things to find the appropriate was to do the
conversion.

In practice, of course, most of the time, the base class will
have a copy constructor, which will take a reference to base.
Which means that if no better conversion is available, it will
be used. When this happens accidentally, it is called slicing.
int main()
{
B obj;
fun(obj); // obj is sliced into type of A, but how
exactly does it happen?
The compiler constructs a temporary of type 'A' from the 'A' part
of the 'obj' (using the appropriate copy constructor).
In practice. Note however that the copy constructor of A could
call virtual functions on the object being copied, which would
result in the derived type being taken into account. (Of
course, the compiler generated copy constructor doesn't do this,
and I can't say off hand that I've seen any user defined copy
constructors which do it either. But it is possible.)
Any 'B' obejct contains the 'A' part, and then some other
stuff that makes it different from an 'A' object. The other
stuff is ignored during copying.
By the compiler generated copy constructor.
}
I noticed that the copy constructor of A is invoked and
"thinking in c++" claims that to be essential for updating
the vptr (if present) with the proper VTABLE. [this is not
in the above case]
The copy constructor invocation is essential for the process.
But the vtbl is not the reason.
Not the only reason. The vptr *is* one reason why a constructor
is *always* called when creating an object.
The object created by the slicing process has to be changeable
(inside your 'fun' function), and should not cause any changes
in the originating 'obj'. That's why a different object (a
temporary) is constructed.
In my experience, inheritance doesn't work well with assignment
and copy; if a class is designed to be used as a base class,
most of the time, you should block copy and assignment (or force
copy to go through a virtual function, such as clone). And if a
class isn't designed to be used as a base class, it's generally
an error to derived from it. The result is that if you've done
any design up front, and you're religious about blocking copy
and assignment when they're not wanted, slicing isn't a problem.

Also, of course, it's fairly rare to derive from a concrete
class. And if the base class is abstract, you can't slice to
it, since no instances of it can exist.

--
James Kanze (GABI Software) email:ja*********@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
Dec 13 '07 #3

This discussion thread is closed

Replies have been disabled for this discussion.