C++ Object Slicing with Example

In this tutorial, we are going to see how object slicing in C++. Before diving into the topic let us revise two simple concepts of object oriented programming.

  • Inheritance
  • Polymorphism

Inheritance is said to be an IS-A relationship. For e.g.

class Animal {
	// properties common to all animals
} 

class Tiger: public Animal {
	// properties specific to the tiger.
}

Here Tiger class will inherit all the properties of the animal class and will add some more properties which are specific to Tiger to it. Here, therefore, we can say that:

Every Tiger IS-A Animal

So while writing code an animal class reference can be used to point to tiger class. This same phenomenon can be used in code which is known as polymorphism when one object can take different forms.

C++ Object Slicing

Object slicing refers to the property of object losing some of its properties when it is pointed by the reference of its parent class. The additional attributes of the derived class are sliced off of the object. In our above example if we write:

Tiger t;
Animal a = t;

Then the object will not have any properties of tiger, the properties specific to the tiger will be sliced off and a will now only contain the properties common to all animals.

Let’s take a simple example:

#include <iostream>
using namespace std;


class Base {

	public :
		int x,y;
		int return10() {
			return 10;
		}
		
		Base() {
			x = 1;
			y = 2;
		}

};

class Derived : public Base {

	public : 
		int z;
		int return10() {
			return 100;
		}
		
		Derived() {
			z = 3;
		}
	
};

int main() {
	
	Derived d;
	cout<<d.return10()<<" "<<d.x<<" "<<d.z<<endl;
	
	d.x = 5;
	Base b = d,a;
	
	cout<<"Size of original Derived object : "<<sizeof(d)<<endl;
	cout<<"Size of original Base object : "<<" "<<sizeof(a)<<endl;
	cout<<"Size of original Sliced object : "<<sizeof(b)<<endl;
	
	cout<<d.return10()<<" "<<d.x<<" "<<d.z<<endl;
	cout<<b.return10()<<" "<<b.x<<endl;
	
	return 0;
}

Output:

100 1 3
Size of original Derived object : 12
Size of original Base object : 8
Size of original Sliced object : 8
100 5 3
10 5

If we change the line:

cout<<b.return10()<<" "<<b.x<<endl;

to

cout<<b.return10()<<" "<<b.z<<endl;

we will get an error saying:

error: ‘class Base’ has no member named ‘z’

Here the object b is sliced copy of object d. The same is evident from the size of the objects.

Object slicing can be prevented if use pointers or references the example below depicts the same.

Keeping all the other code same if we change the main function to:

int main() {
	
	Derived *pointerd = new Derived();
	Base *pointerb = new Base();
	Base *inheritedb = new Derived();
	
	cout<<pointerd->x<<" "<<pointerd->z<<endl;
	cout<<inheritedb->x<<endl;
	
	return 0;
}

Output:

1 3
1

Here also we cant directly use:

cout<<inheritedb->z<<endl;

Which will give us the same error instead what we can do is first cast the pointer of Base class to a Derived class pointer and then access the z variable which will look as below:

int main() {
	
	Derived *pointerd = new Derived();
	Base *pointerb = new Base();
	Base *inheritedb = new Derived();
	
	cout<<pointerd->x<<" "<<pointerd->z<<endl;
	cout<<((Derived *)inheritedb)->x<<endl;
	
	return 0;
}

Output:

1 3
1

Note that if we try to print the size of pointerd or any other reference we will get the same size as pointers to any type or class will take the same size. Here, therefore, the objects are not sliced but the properties are hidden from the user which can be accessed after doing a simple cast.

Comment down below if you have any queries related to object slicing in C++.

Leave a Comment

Your email address will not be published. Required fields are marked *