-
Up-casting and Object SlicingC++ 2014. 2. 14. 07:39
Up-casting은 Polymorphism에서 상위 클래스 타이프로 하위클래스의 객체를 복사할 때 발생을 한다.
이 때 생성되는 객체는 기본적으로 하위 클래스의 멤버를 완전히 잃어 버리고 상위 클래스의 멤버만을 갖게 된다.좀 더 깊이 생각을 해보면 1)의 예에서는 상위클래스의 default Assignment Operator가 호출이 되어 이미 생성된 하위 클래스의 객체를 복사를 하는 데 상위클래스의 클래스의 멤버만이 복사가 된다. 따라서 멤버함수가 Virtual 이 선언이 되어 있어도 더 이상 찾아볼 하위 멤버함수가 없다.
따라서 상위 멤버 함수가 수행이 된다. 이것이 Slicing이다.
2)의 예에서 보면 ref는 이미 생성이 된 하위 클래스의 객체의 참조값만을 상위 클래스의 default Assignment Operator에 의해 복사를 하였다. 하위 클래스 객체의 주소가 복사가 된 것이므로 멤버함수가 Virtual 이 선언된 경우 virtual 의 속성에 따라 하위 클래스를 찾아가게 된다.
혼돈하면 안 되는 것이 어떤 경우에도 Up-casting이 발생하는 경우 하위 클래스 멤버들은 scope 밖에 있어 보이질 않는다.
3)의 경우 같이 포인터를 사용하는 경우도 Reference를 사용하는 경우와 동일하다.
Main()
{
Second ps1;
ps1.print(); 하위 클래스의 print() 호출
1) First first = ps1; // slicing이 발생
first.print(); 상위 클래스의 print() 호출
2) First& ref = ps1;
ref.print(); 하위 클래스의 print() 호출
ref.second(); //error3) First *pf2 = new Second();
pf2->print(); 하위 클래스의 print() 호출
delete pf2;
}
Class First
{
virtual void print();
int getFirst();
}Class Second : First
{
virtual void print();
int getSecond();
}Slicing을 피하는 방법
- Reference나 Pointer를 이용한다. 가능하면 Reference가 안전하다.
- 좀 복잡하긴 해도 상위 클래스에서 default assignment operator를 재정의 하여 dynamic type casting을 통해 이를 구현한다
절대 비추, 그냥 개념을 이해하기 위해 퍼온 코드임
class A {
public:
virtual A& operator= (const A& a) {
assign(a);
return *this;
}
protected:
void assign(const A& a) {
// copy members of A from a to this
}
};
class B : public A {
public:
virtual B& operator= (const A& a) {
if (const B* b = dynamic_cast<const B*>(&a))
assign(*b);
else
throw bad_assignment();
return *this;
}
protected:
void assign(const B& b) {
A::assign(b); // Let A's assign() copy members of A from b to this
// copy members of B from b to this
}
}
'C++' 카테고리의 다른 글
STL Container 선택 (0) 2014.02.17 Inheritance 에서 copy operator & assignment operator (0) 2014.02.15 Polymophism의 사용 (0) 2014.02.14 Overriding과 Virtual (0) 2014.02.14 Inheritance에서 virtual destructor (0) 2014.02.14