Monday 14 July 2014

Object Slicing in C++

What is Object slicing?

When a Derived Class object is assigned to Base class, the base class' contents in the derived object are copied to the base class leaving behind the derived class specific contents. This is referred as Object Slicing. That is, the base class object can access only the base class members. This also implies the separation of base class members from derived class members has happened.

class b { int i, j; };
class d : public b { int k; };
int main()
{
    d d1;
    b b1 = d1; // Object Slicing,  k of d is sliced off
}

here b contains i and j where as d contains i, j& k. On assignment only i and j of the d get copied into i and j of b. k does not get copied. on the effect object d1 got sliced.


#include <iostream>
using namespace std;
class Base
{
protected:
     int i;
public:
     Base(int a)
     {
i = a;
}
     virtual void display()
     {
cout << "I am Base class object, i = " << i << endl; }
};
class Derived : public Base
{
    int j;
public:
    Derived(int a, int b) : Base(a) { j = b; }
    virtual void display()
    {
cout << "I am Derived class object, i = " << i << ", j = " << j << endl;  }
};
// Global method, Base class object is passed by value
void somefunc (Base obj)
{
    obj.display();
}
int main()
{
    Base b(33);
    Derived d(45, 54);
    somefunc(b);
    somefunc(d);  // Object Slicing, the member j of d is sliced off
    return 0;
}
Output:
I am Base class object, i = 33
I am Base class object, i = 45
How to avoid ? 

We can avoid above unexpected behavior with the use of pointers or references. Object slicing doesn’t occur when pointers or references to objects are passed as function arguments since a pointer or reference of any type takes same amount of memory. For example, if we change the global method myfunc() in the above program to following, object slicing doesn’t happen.
// rest of code is similar to above
void somefunc (Base &obj)
{
    obj.display();
}          
// rest of code is similar to above
Output:
I am Base class object, i = 33
I am Derived class object, i = 45, j = 54
We get the same output if we use pointers and change the program to following.
// rest of code is similar to above
void somefunc (Base *objp)
{
    objp->display();
}
int main()
{
    Base *bp = new Base(33) ;
    Derived *dp = new Derived(45, 54);
    somefunc(bp);
    somefunc(dp);  // No Object Slicing
    return 0;
}
Output:
I am Base class object, i = 33
I am Derived class object, i = 45, j = 54


No comments:

Post a Comment