← Back to C++ Course | Chapter 10: Polymorphism & Abstraction | Lesson 10 of 11

C++ Object Slicing

What is Object Slicing?

Object slicing happens when a derived-class object is assigned to a plain base-class object by value: since the base object only has room for the base class's members, all of the derived class's additional data is 'sliced off' and lost in the assignment.

Example: What is Object Slicing?

cpp
#include <iostream>
#include <string>

class Animal {
public:
	int legs = 4;
};

class Dog : public Animal {
public:
	std::string breed = "Labrador";
};

int main() {
	Dog d;
	Animal a = d;
	std::cout << a.legs << std::endl;
	return 0;
}

Slicing on Value Assignment

When you assign a derived object directly into an already-declared base-class variable, the base class's copy-assignment operator runs, and it simply has no knowledge of — or room for — the derived class's extra members, so they're discarded entirely.

Example: Slicing on Value Assignment

cpp
#include <iostream>

class Animal {
public:
	virtual void speak() { std::cout << "Animal" << std::endl; }
};

class Dog : public Animal {
public:
	void speak() override { std::cout << "Dog" << std::endl; }
};

int main() {
	Dog d;
	Animal a = d;
	a.speak();
	return 0;
}

Slicing on Pass-by-Value

Passing a derived object into a function that accepts its parameter by value (as a plain base-class type) triggers the base class's copy constructor inside that call, which slices the object down to just its base portion before the function body even starts running.

Example: Slicing on Pass-by-Value

cpp
#include <iostream>

class Animal {
public:
	virtual void speak() { std::cout << "Animal" << std::endl; }
};

class Dog : public Animal {
public:
	void speak() override { std::cout << "Dog" << std::endl; }
};

void makeSpeak(Animal a) {
	a.speak();
}

int main() {
	Dog d;
	makeSpeak(d);
	return 0;
}

Preventing Slicing with Pointers

To prevent slicing and preserve an object's full polymorphic behavior, always pass and store derived objects using base class pointers rather than base class values — a pointer just holds an address, so there's nothing to slice.

Example: Preventing Slicing with Pointers

cpp
#include <iostream>

class Animal {
public:
	virtual void speak() { std::cout << "Animal" << std::endl; }
};

class Dog : public Animal {
public:
	void speak() override { std::cout << "Dog" << std::endl; }
};

void makeSpeak(Animal *a) {
	a->speak();
}

int main() {
	Dog d;
	makeSpeak(&d);
	return 0;
}

Preventing Slicing with References

You can achieve the same protection using base class references instead of pointers: passing a derived object to a function parameter typed as a base class reference avoids triggering any copy at all, so the object's derived members stay intact.

Example: Preventing Slicing with References

cpp
#include <iostream>

class Animal {
public:
	virtual void speak() { std::cout << "Animal" << std::endl; }
};

class Dog : public Animal {
public:
	void speak() override { std::cout << "Dog" << std::endl; }
};

void makeSpeak(Animal &a) {
	a.speak();
}

int main() {
	Dog d;
	makeSpeak(d);
	return 0;
}

Login to run this code

C/C++/Java/PHP execution requires a free account. Your code is saved — you'll land right back in the editor after logging in.