Question
What Is Object Slicing in C++? Explanation, Examples, and How to Avoid It
Question
In C++, what does object slicing mean, and in which situations does it occur?
For example, how does slicing affect a derived object when it is copied or assigned to a base-class object?
Short Answer
By the end of this page, you will understand what object slicing is in C++, why it happens when a derived object is copied into a base object by value, what data gets lost, and how to avoid the problem using references, pointers, and better class design.
Concept
Object slicing happens in C++ when a derived-class object is copied into a base-class object by value.
When that happens, only the base part of the object is copied. The extra members and behavior that belong to the derived class are sliced off.
Why this happens
A derived object contains:
- the base-class portion
- plus its own additional data and behavior
If you create a separate base object from that derived object, the new object can only store the base portion. The derived-specific part does not fit inside a plain base object.
Example idea
If Dog inherits from Animal, then a Dog object contains an Animal part plus anything specific to Dog.
If you do this:
Dog d;
Animal a = d;
then a becomes a standalone Animal object. It is not a Dog. The Dog-specific state is lost.
Why it matters
Object slicing can cause:
- loss of derived-class data
- unexpected behavior when calling methods
- bugs in containers or function calls that copy polymorphic objects by value
This is especially important in object-oriented C++ code that uses inheritance and polymorphism.
Mental Model
Think of a derived object as a larger box that contains a smaller base box inside it.
Base= the inner boxDerived= the inner box plus extra space
When you copy a Derived object into a Base variable, C++ only copies the inner Base box.
The extra part of the larger box is left behind.
That is why it is called slicing: the derived-specific part is cut off, and only the base part remains.
Syntax and Examples
The key rule is simple:
Slicing occurs with copy by value
class Base {
public:
int x = 1;
};
class Derived : public Base {
public:
int y = 2;
};
int main() {
Derived d;
Base b = d; // object slicing
}
Here, b only stores the Base part of d. The y member does not exist in b.
Example with methods
#include <iostream>
using namespace std;
class Animal {
public:
virtual void speak() const {
cout << ;
}
};
: Animal {
:
{
cout << ;
}
};
{
Dog dog;
Animal animal = dog;
dog.();
animal.();
}
Step by Step Execution
Consider this example:
#include <iostream>
using namespace std;
class Base {
public:
int a = 10;
};
class Derived : public Base {
public:
int b = 20;
};
int main() {
Derived d;
Base baseObj = d;
cout << baseObj.a << "\n";
}
Step by step
-
Derived d;- A
Derivedobject is created. - It contains:
- the
Basepart witha = 10 - the
Derivedpart withb = 20
- the
- A
-
Base baseObj = d;
Real World Use Cases
Object slicing often appears accidentally in real programs.
1. Passing objects to functions by value
void printAnimal(Animal a) {
a.speak();
}
If you call printAnimal(dog);, the Dog object is sliced into an Animal copy.
Better:
void printAnimal(const Animal& a) {
a.speak();
}
2. Storing derived objects in a container of base objects
vector<Animal> animals;
animals.push_back(Dog()); // slicing
Each element in vector<Animal> is an actual Animal object, so derived parts are lost.
Better approaches:
vector<Animal*>vector<shared_ptr<Animal>>
Real Codebase Usage
In real C++ codebases, developers usually avoid polymorphic objects being copied by value.
Common patterns
Pass base types by reference
void process(const Animal& animal) {
animal.speak();
}
This avoids copying and preserves polymorphism.
Store polymorphic objects through pointers
#include <memory>
#include <vector>
vector<unique_ptr<Animal>> animals;
animals.push_back(make_unique<Dog>());
This keeps the real runtime type.
Use virtual destructors in polymorphic base classes
class Animal {
public:
virtual ~Animal() = default;
virtual void speak() const = 0;
};
If you use base pointers or references, a virtual destructor is important for correct cleanup.
Common Mistakes
1. Passing a base class by value
Broken code:
void makeSpeak(Animal a) {
a.speak();
}
Problem:
- Passing by value creates a new
Animalobject. - A
Dogargument gets sliced.
Fix:
void makeSpeak(const Animal& a) {
a.speak();
}
2. Using vector<Base> for polymorphic objects
Broken code:
vector<Animal> animals;
animals.push_back(Dog());
animals.push_back(Cat());
Problem:
- The container stores actual
Animalobjects. DogandCatparts are sliced off.
Comparisons
| Situation | Slicing? | Why |
|---|---|---|
Base b = derived; | Yes | Creates a new base object by value |
Base& b = derived; | No | Reference refers to original derived object |
Base* b = &derived; | No | Pointer points to original derived object |
void f(Base b) | Yes | Function parameter copies by value |
void f(const Base& b) | No | No copy is made |
vector<Base> with derived inserts | Yes | Container stores base objects |
Cheat Sheet
Quick definition
Object slicing happens when a derived object is copied into a base object by value, causing the derived-specific part to be lost.
Common slicing cases
Base b = derived;
Base b(derived);
b = derived;
void func(Base b); // slicing if called with derived
vector<Base> items;
items.push_back(derived); // slicing
Safe alternatives
void func(const Base& b);
void func(Base* b);
Base& ref = derived;
Base* ptr = &derived;
vector<unique_ptr<Base>> items;
Key rule
- By value can slice
- does not slice
FAQ
What is object slicing in simple terms?
Object slicing is when a derived object is copied into a base object, and the derived-specific part is lost.
When does object slicing occur in C++?
It occurs when a derived object is passed, returned, assigned, or stored by value as a base type.
Does object slicing happen with references?
No. References do not create a new base object, so the full derived object remains intact.
Does object slicing happen with pointers?
No. A pointer just points to the original object, so no slicing occurs.
Do virtual functions stop object slicing?
No. Virtual functions help with dynamic dispatch, but they do not stop copying a derived object into a base object.
Can STL containers cause object slicing?
Yes. For example, vector<Base> will slice derived objects inserted by value.
How do I avoid object slicing in C++?
Use references or pointers for polymorphic types, and prefer smart pointers in containers and factory functions.
Is slicing always a bug?
Usually in polymorphic designs, yes. In some rare cases, copying only the base part may be intentional, but it should be a deliberate design choice.
Mini Project
Description
Build a small C++ program that demonstrates object slicing and then fixes it. The program will model animals with a base class and a derived class. First, you will pass a derived object to a function by value and observe the slicing. Then you will change the function to use a reference and compare the result. This project is useful because it shows the exact bug beginners often encounter in class hierarchies.
Goal
Create a program that shows the difference between passing a derived object by value and by reference in C++.
Requirements
- Create a base class with a virtual method.
- Create a derived class that overrides that method.
- Write one function that accepts the base type by value.
- Write another function that accepts the base type by reference.
- Call both functions with a derived object and compare the output.
Keep learning
Related questions
Basic Rules and Idioms for Operator Overloading in C++
Learn the core rules, syntax, and common idioms for operator overloading in C++, including member vs non-member operators.
C++ Base Class Constructor Rules Explained
Learn how C++ base class constructors are called from derived classes, including order, syntax, defaults, and common mistakes.
C++ Casts Explained: C-Style Cast vs static_cast vs dynamic_cast
Learn the difference between C-style casts, static_cast, and dynamic_cast in C++ with clear examples, safety rules, and real usage tips.