본문으로 건너뛰기
Previous
Next
C++ Slicing Problem — Complete Guide

C++ Slicing Problem — Complete Guide

C++ Slicing Problem — Complete Guide

이 글의 핵심

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:

  • y member 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

  1. Slicing: Derived members lost when copying to base type
  2. Polymorphism loss: Virtual functions ignored
  3. Solution: Use reference or pointer
  4. Prevention: Delete copy constructor
  5. 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

Master slicing prevention for safer C++ polymorphism! 🚀


자주 묻는 질문 (FAQ)

Q. 이 내용을 실무에서 언제 쓰나요?

A. Everything about C++ Slicing Problem : from basic concepts to practical applications. Master key content quickly with ex… 실무에서는 위 본문의 예제와 선택 가이드를 참고해 적용하면 됩니다.

Q. 선행으로 읽으면 좋은 글은?

A. 각 글 하단의 이전 글 또는 관련 글 링크를 따라가면 순서대로 배울 수 있습니다. C++ 시리즈 목차에서 전체 흐름을 확인할 수 있습니다.

Q. 더 깊이 공부하려면?

A. cppreference와 해당 라이브러리 공식 문서를 참고하세요. 글 말미의 참고 자료 링크도 활용하면 좋습니다.


이 글에서 다루는 키워드 (관련 검색어)

C++, slicing, inheritance, polymorphism, copy, reference, pointer 등으로 검색하시면 이 글이 도움이 됩니다.