C++ Slicing Problem | 'Object Got Sliced' Inheritance Copy Error Solution
이 글의 핵심
C++ slicing problem C++, slicing, "object, Introduction: "Copied derived class but data disappeared" explained in detail with practical examples.
Introduction: “Copied Derived Class but Data Disappeared"
"Polymorphism Not Working”
In C++, when copying derived class object to base class type, derived class members get sliced off causing slicing problem.
// ❌ Slicing problem
class Animal {
public:
virtual void speak() {
std::cout << "Animal sound\n";
}
};
class Dog : public Animal {
std::string name_;
public:
Dog(const std::string& name) : name_(name) {}
void speak() override {
std::cout << name_ << " barks\n";
}
};
void makeSound(Animal animal) { // ❌ Pass by value
animal.speak();
}
int main() {
Dog dog("Buddy");
makeSound(dog); // ❌ Slicing occurs
// Output: Animal sound (Dog got sliced!)
}
What This Guide Covers:
- What is slicing problem?
- Polymorphism loss
- Solution with reference/pointer
- Copy prevention pattern
1. What is Slicing Problem?
Slicing Occurs
Here is detailed implementation code using C++. Define a class to encapsulate data and functionality. Understand the role of each part while examining the code.
class Base {
public:
int x = 1;
virtual void foo() {
std::cout << "Base::foo\n";
}
};
class Derived : public Base {
public:
int y = 2; // Derived class member
void foo() override {
std::cout << "Derived::foo\n";
}
};
int main() {
Derived d;
Base b = d; // ❌ Slicing occurs
std::cout << b.x << '\n'; // 1
// std::cout << b.y << '\n'; // Compile error: no y
b.foo(); // Base::foo (polymorphism lost)
}
Problems:
ymember lost- Polymorphism lost (virtual ignored)
- vtable pointer not copied
2. Polymorphism Loss
Example 1: Function Argument
Below is an implementation example using C++. Understand the role of each part while examining the code.
// ❌ Pass by value
void process(Animal animal) { // Slicing
animal.speak(); // Animal::speak called
}
Dog dog("Buddy");
process(dog); // Animal sound (polymorphism lost)
// ✅ Pass by reference
void process(Animal& animal) { // No slicing
animal.speak(); // Dog::speak called
}
process(dog); // Buddy barks (polymorphism preserved)
Example 2: Container
Below is an implementation example using C++. Try running the code directly to check its operation.
// ❌ vector<Base>
std::vector<Animal> animals;
animals.push_back(Dog("Buddy")); // Slicing
animals[0].speak(); // Animal sound
// ✅ vector<unique_ptr<Base>>
std::vector<std::unique_ptr<Animal>> animals;
animals.push_back(std::make_unique<Dog>("Buddy"));
animals[0]->speak(); // Buddy barks
3. Solution: Reference/Pointer
Solution 1: Use Reference
Below is an implementation example using C++. Try running the code directly to check its operation.
// ✅ Reference
void process(const Animal& animal) {
animal.speak();
}
Dog dog("Buddy");
process(dog); // Buddy barks
Solution 2: Use Pointer
Below is an implementation example using C++. Perform branching with conditionals. Try running the code directly to check its operation.
// ✅ Pointer
void process(Animal* animal) {
if (animal) {
animal->speak();
}
}
Dog dog("Buddy");
process(&dog); // Buddy barks
Solution 3: Smart Pointer
Below is an implementation example using C++. Understand the role of each part while examining the code.
// ✅ unique_ptr
void process(std::unique_ptr<Animal> animal) {
animal->speak();
}
process(std::make_unique<Dog>("Buddy")); // Buddy barks
// ✅ shared_ptr
void process(std::shared_ptr<Animal> animal) {
animal->speak();
}
process(std::make_shared<Dog>("Buddy")); // Buddy barks
4. Copy Prevention Pattern
Pattern 1: Delete Copy Constructor
Here is detailed implementation code using C++. Define a class to encapsulate data and functionality. Understand the role of each part while examining the code.
class Animal {
public:
Animal() = default;
Animal(const Animal&) = delete; // Prevent copy
Animal& operator=(const Animal&) = delete;
virtual ~Animal() = default;
virtual void speak() = 0;
};
class Dog : public Animal {
public:
void speak() override {
std::cout << "Bark\n";
}
};
int main() {
Dog dog;
// Animal a = dog; // Compile error
}
Summary
Key Points
- Slicing: Derived members lost when copying to base type
- Polymorphism loss: Virtual functions ignored
- Solution: Use reference or pointer
- Prevention: Delete copy constructor
- Container: Store pointers, not objects
When to Use
✅ Prevent slicing by:
- Using reference/pointer
- Deleting copy constructor
- Using smart pointers
- Storing pointers in containers
❌ Don’t:
- Pass polymorphic objects by value
- Store polymorphic objects directly in containers
- Copy derived to base type
Best Practices
- ✅ Always use reference/pointer for polymorphism
- ✅ Delete copy constructor in base class
- ✅ Use smart pointers for ownership
- ❌ Don’t pass polymorphic objects by value
- ❌ Don’t store objects in vector
Related Articles
- C++ Virtual Destructor
- C++ Inheritance and Polymorphism
- C++ Polymorphism Composition Variant
Master slicing prevention for safer C++ polymorphism! 🚀