C++ Object Slicing
In this page:
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?
#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;
}
Login to try C/C++/Java/PHP code in the editor
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
#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;
}
Login to try C/C++/Java/PHP code in the editor
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
#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 try C/C++/Java/PHP code in the editor
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
#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 try C/C++/Java/PHP code in the editor
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
#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 try C/C++/Java/PHP code in the editor
Chapter Quiz — Complete all 11 topics to unlock
0/11 topics done
Complete these topics first: