Object Slicing in C++

Object slicing is a situation in C++ when a derived class object is assigned to a base class object, the additional attributes of a derived class object are sliced off (not considered) to form the base class object.

Key points to note:

  • In C++, a derived class object can be assigned to a base class object, but the other way is not possible.
  • Object slicing does not 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.
  • Object slicing can be prevented by making the base class function pure virtual there by disallowing object creation. It is not possible to create the object of a class which contains a pure virtual method.

We have provide a lot of examples to demonstrate the above points. Go through them to get a better idea.

Code to demonstrate object slicing:


#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;  
     }
}; 
// Base class object is passed by value
void print_object(Base obj)
{
    obj.display();
} 
int main()
{
    Base a(1);
    Derived b(2, 3);
    print_object(a);
    print_object(b);  // Object Slicing, the member j of b is sliced off
    return 0;
}

Output of the above code:


I am Base class object, i = 1
I am Base class object, i = 2

Point demonstrated: "Object slicing doesn’t occur when pointers or references to objects are passed as function arguments"

Consider the following code:


#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;  
      }
}; 
// Base class object is passed by value
void print_object(Base &obj)
{
    obj.display();
} 
int main()
{
    Base a(1);
    Derived b(2, 3);
    print_object(a);
    print_object(b);  // No Object Slicing
    return 0;
}

Note the function parameter:


void print_object (Base &obj)

Output of the above code:


I am Base class object, i = 1
I am Derived class object, i = 2, j = 3

Same result is achieved if we use pointers as demonstrated below:


void print_object(Base *objp)
{
    objp->display();
} 
int main()
{
    Base *a = new Base(1) ;
    Derived *b = new Derived(2, 3);
    print_object(a);
    print_object(b);  // No Object Slicing
    return 0;
}

If you have any questions or need any clarifications, do leave a comment and we will get back to you as soon as possible.

Enjoy!