Thursday, 27 November 2014

Object Slicing in C++ with examples

What is Object Slicing in C++?

Object Slicing is occurred when a derived class object is passed by value as a BaseCls  class object, the base class copy constructor is called. We know that using virtual functions concept.

Here the derived class object are sliced off.  if we upcast (Upcasting and downcasting) to  an object instead of a pointer or reference, the object is sliced.

See the below example how the object is sliced off:

#include <vector>
class BaseCls {};
class DerivedCls : public BaseCls {};
int main ()
 vector<BaseCls> ocVect;
 DerivedCls ocDerived;
 return 0;

Here the base class constructor created it, which is called object slicing.

This is one of the reason we should prefer pass-by-reference to pass-by-value.

See another example for object slicing.

This is not surprising because a base class constructor created it. This is called object slicing. This is one of the reason we should prefer pass-by-reference to pass-by-value. In the case of above example, we should have created a container of pointers rather than the container of objects.

Here is another example of object slicing.
#include <vector>
#include <iostream>
#include <string>
using namespace std;
class BaseCls{
 BaseCls(const string& s) : name(s) {}
 virtual void Show() const {
  cout << "Base: " << name << " Show()" << endl;
 string name;
class DerivedCls : public BaseCls {
 string name;
 string habitat;
 DerivedCls(const string& sp, const string &s, const string &h)
  : BaseCls(sp), name(s), habitat(h) {};
 virtual void Show() const {
  cout << "DerivedCls: " << name << " Show() in " << habitat << endl;
void Fun1(BaseCls a) {
void Fun (const BaseCls &a) {
 a.Show ();
int main()
 BaseCls ocBase("Base");
 DerivedCls ocDerived("Test","Test1","Test1 & Test2");
 cout << "pass-by-value" << endl;
 cout << "\npass-by-reference" << endl;
  getchar ();
  return 0;
Output of the run is:

Base: Base Show()
Base: Test Show()


Base: Base ()
DerivedCls: Test1 Show() in Test1 & Test2
Note that, in main(), we call two functions,
Fun (BaseCls  a) and Fun1(const BaseCls  &a).

The first call is passing an argument by value, the second one is passing an argument by reference.

We might expect the first call to produce Base: Base Show(), and the second to produce DerivedCls: Test1 Show() in Test1 & Test2

In fact, both calls use the base-class version of Show.

What happened here? Strange results, let us predict the output…..

In the pass-by-value case, because Show( ) was invoked by an Base object (rather than a pointer or reference). It caused an object the size of BaseCls to be pushed on the stack. This means that if an object of a class inherited from BaseCls is passed to Show( ), the compiler accepts it, but it copies only the BaseCls portion of the object. It slices the derived portion (such as habitat member) off of the object.

Because the object is being passed by value, the compiler knows the precise type of the object because the derived object has been forced to become a base object. When passing by value, the copy-constructor for a BaseCls object is used, which initializes the vptr (virtual table pointer) to the Base vtbl (virtual table) and copies only the BaseCls parts of the object. There's no explicit copy-constructor here, so the compiler somehow makes one.

The DerivedCls object lost all the things that make it Derived-like, and it becomes an BaseCls during slicing. 

No comments: