472,794 Members | 2,247 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 472,794 software developers and data experts.

object slicing

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
2 4617
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
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 thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

11
by: hokiegal99 | last post by:
How would I determine if a filename is greater than a certain number of characters and then truncate it to that number? For example a file named XXXXXXXXX.txt would become XXXXXX fname = files...
5
by: Jeff Greenberg | last post by:
Not an experienced c++ programmer here and I've gotten myself a bit stuck. I'm trying to implement a class lib and I've run into a sticky problem that I can't solve. I'd appreciate any help that I...
10
by: Tony Johansson | last post by:
Hello Experts!! This class template and main works perfectly fine. I have this class template called Handle that has a pointer declared as T* body; As you can see I have a reference counter in...
8
by: Tom Wilson | last post by:
Is there a way to pass a derived object so that the called function thinks it is the base class? Here's the lowdown. class Hull { // .... virtual int DoIt() { TRACE("Hull"); } // ....
17
by: baibaichen | last post by:
i have written some code to verify how to disable slicing copy according C++ Gotchas item 30 the follow is my class hierarchy, and note that B is abstract class!! class B { public: explicit...
0
by: Travis Oliphant | last post by:
This post is to gather feedback from the wider community on PEP 357. It is nearing the acceptance stage and has previously been discussed on python-dev. This is a chance for the wider Python...
5
by: Anunay | last post by:
Hello all, Can you explain me the basic concept of "OBJECT SPLICING" ? When does it occur? Thanks, Anunay
2
by: maynard | last post by:
I have defined a template class (tree data structure) that uses dynamic memory and has properly implemented ctor's, dtor and assignment operator. I can observe the address of my tree object prior...
1
by: subramanian100in | last post by:
Consider class Base { .... }; class Derived : public Base { ...
3
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 2 August 2023 starting at 18:00 UK time (6PM UTC+1) and finishing at about 19:15 (7.15PM) The start time is equivalent to 19:00 (7PM) in Central...
0
by: erikbower65 | last post by:
Using CodiumAI's pr-agent is simple and powerful. Follow these steps: 1. Install CodiumAI CLI: Ensure Node.js is installed, then run 'npm install -g codiumai' in the terminal. 2. Connect to...
0
by: erikbower65 | last post by:
Here's a concise step-by-step guide for manually installing IntelliJ IDEA: 1. Download: Visit the official JetBrains website and download the IntelliJ IDEA Community or Ultimate edition based on...
0
by: kcodez | last post by:
As a H5 game development enthusiast, I recently wrote a very interesting little game - Toy Claw ((http://claw.kjeek.com/))。Here I will summarize and share the development experience here, and hope it...
2
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 6 Sept 2023 starting at 18:00 UK time (6PM UTC+1) and finishing at about 19:15 (7.15PM) The start time is equivalent to 19:00 (7PM) in Central...
14
DJRhino1175
by: DJRhino1175 | last post by:
When I run this code I get an error, its Run-time error# 424 Object required...This is my first attempt at doing something like this. I test the entire code and it worked until I added this - If...
0
by: lllomh | last post by:
How does React native implement an English player?
0
by: Mushico | last post by:
How to calculate date of retirement from date of birth
2
by: DJRhino | last post by:
Was curious if anyone else was having this same issue or not.... I was just Up/Down graded to windows 11 and now my access combo boxes are not acting right. With win 10 I could start typing...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.