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

C++ Object Slicing

Object slicing happens when a child object is copied into a parent variable and its extra parts are cut off, like slicing a sandwich and losing the top layer. Using pointers or references avoids it.
Syntax
cpp
class Base { /* members */ };
class Derived : public Base { /* extra members */ };

Derived d;
Base b = d;   // slicing: only the Base part is copied

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 std::cout and std::cin
#include <iostream>
// Include std::string
#include <string>

// Define the type Animal
class Animal {
// Members below can be accessed from outside the class
public:
	int legs = 4;
};

// Define the type Dog
class Dog : public Animal {
// Members below can be accessed from outside the class
public:
	std::string breed = "Labrador";
};

// Program execution starts in main()
int main() {
	Dog d;
	Animal a = d;
	// Print to the console with cout
	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 std::cout and std::cin
#include <iostream>

// Define the type Animal
class Animal {
// Members below can be accessed from outside the class
public:
	virtual void speak() { std::cout << "Animal" << std::endl; }
};

// Define the type Dog
class Dog : public Animal {
// Members below can be accessed from outside the class
public:
	void speak() override { std::cout << "Dog" << std::endl; }
};

// Program execution starts in main()
int main() {
	Dog d;
	Animal a = d;
	a.speak();
	// Return 0 to signal that the program finished successfully
	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 std::cout and std::cin
#include <iostream>

// Define the type Animal
class Animal {
// Members below can be accessed from outside the class
public:
	virtual void speak() { std::cout << "Animal" << std::endl; }
};

// Define the type Dog
class Dog : public Animal {
// Members below can be accessed from outside the class
public:
	void speak() override { std::cout << "Dog" << std::endl; }
};

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

// Program execution starts in main()
int main() {
	Dog d;
	makeSpeak(d);
	// Return 0 to signal that the program finished successfully
	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 std::cout and std::cin
#include <iostream>

// Define the type Animal
class Animal {
// Members below can be accessed from outside the class
public:
	virtual void speak() { std::cout << "Animal" << std::endl; }
};

// Define the type Dog
class Dog : public Animal {
// Members below can be accessed from outside the class
public:
	void speak() override { std::cout << "Dog" << std::endl; }
};

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

// Program execution starts in main()
int main() {
	Dog d;
	makeSpeak(&d);
	// Return 0 to signal that the program finished successfully
	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 std::cout and std::cin
#include <iostream>

// Define the type Animal
class Animal {
// Members below can be accessed from outside the class
public:
	virtual void speak() { std::cout << "Animal" << std::endl; }
};

// Define the type Dog
class Dog : public Animal {
// Members below can be accessed from outside the class
public:
	void speak() override { std::cout << "Dog" << std::endl; }
};

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

// Program execution starts in main()
int main() {
	Dog d;
	makeSpeak(d);
	// Return 0 to signal that the program finished successfully
	return 0;
}
Related Topics
{# common_mistakes/chapter_summary/browser_support: on Hindi pages the view already swaps in the hi_ translation fields (or blanks these out if untranslated), so this renders correctly for both languages without a lang_code check here. #}
Common Mistakes
  1. Assigning a derived object to a base variable by value, which slices off the derived members.
  2. Passing a derived object by value to a function that takes a base parameter.
  3. Storing derived objects in a vector<Base>, which copies only the base part; store pointers instead.

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.