Computer >> 컴퓨터 >  >> 프로그래밍 >> C++

C++ 객체 슬라이싱(Object Slicing) 완벽 정리: 개념부터 예제까지

C++ 객체 슬라이싱(Object Slicing)이란?

객체 슬라이싱(Object Slicing)은 파생 클래스(자식 클래스)의 객체를 기반 클래스(부모 클래스)의 인스턴스에 할당할 때 발생하는 현상을 설명하는 용어입니다. 이 과정에서 파생 클래스에만 존재하는 메서드와 멤버 변수들이 사라지게 되는데, 마치 정보가 잘려나간 것처럼 표현된다고 하여 '슬라이싱'이라고 부릅니다.

다음 예제를 통해 살펴보겠습니다.

class Foo {
    int a;
};
class Bar : public Foo {
    int b;
}

Bar 클래스는 Foo 클래스를 상속하므로, 멤버 변수 ab 두 개를 모두 가지게 됩니다.

그런데 Bar 타입의 변수 bar를 생성한 뒤, Foo 타입의 변수에 이를 할당하면 어떻게 될까요?

Bar bar;
Foo foo = bar;

이 경우 bar가 가지고 있던 멤버 변수 b에 대한 정보는 사라지고, 기반 클래스인 Foo에 정의된 a만 남게 됩니다. 이처럼 파생 클래스의 고유한 멤버가 잘려나가는 현상을 멤버 슬라이싱(member slicing), 즉 객체 슬라이싱이라고 합니다.

객체 슬라이싱이 발생하는 이유

Foo foo = bar;처럼 값을 직접 대입하면, 컴파일러는 기반 클래스인 Foo의 복사 생성자를 호출합니다. 이때 Foo는 자신이 정의한 멤버(a)만 복사할 수 있기 때문에, Bar에 추가된 b는 복사되지 않고 그대로 버려집니다.

객체 슬라이싱을 방지하는 방법

객체 슬라이싱을 피하려면 값(value)이 아닌 참조(reference)나 포인터(pointer)를 사용해야 합니다.

Foo& ref = bar;   // 참조 사용: 슬라이싱 없음
Foo* ptr = &bar;  // 포인터 사용: 슬라이싱 없음

특히 다형성(polymorphism)을 활용해야 하는 상황에서는 가상 함수(virtual function)와 함께 포인터나 참조를 사용하는 것이 C++ 프로그래밍의 일반적인 관례이며, 이를 통해 파생 클래스의 모든 정보를 안전하게 유지할 수 있습니다.