C++ Object Slicing
In this page:
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?
// 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;
}
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 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;
}
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 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;
}
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 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;
}
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 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;
}
Login to try C/C++/Java/PHP code in the editor
- Assigning a derived object to a base variable by value, which slices off the derived members.
- Passing a derived object by value to a function that takes a base parameter.
- Storing derived objects in a
vector<Base>, which copies only the base part; store pointers instead.
Chapter Quiz — Complete all 11 topics to unlock
0/11 topics done
Complete these topics first: