본문 바로가기
번역/Bjarne Stroustrup's C++ Style and Technique FAQ

Why can't I assign a vector<Apple*> to a vector<Fruit*>?

by 겜게준 2020. 3. 4.

왜 vector<Fruit*>에 vector<Apple*>를 대입할 수 없나요?

왜냐하면 타입 시스템에 구멍을 낼 수 있기 때문입니다. 예를 들자면:
class Apple : public Fruit { void apple_fct(); /* ... */ };
class Orange : public Fruit { /* ... */ }; // Orange에는 apple_fct()가 없음

vector<Apple*> v; // Apple들의 vector

void f(vector<Fruit*>& vf) // 순수하게 Fruit를 조작하는 함수
{
vf.push_back(new Orange); // fruit를 담는 vector에 Orange를 추가함
}

void h()
{
f(v); // error: vector<Apple*>를 vector<Fruit*>로 전달할 수 없음
for (int i=0; i<v.size(); ++i) v[i]->apple_fct();
}

f(v)를 호출하는 것이 허용됐다면, Orange를 Apple라고 가장했을 것입니다.

왜 vector<Fruit*>에 vector<Apple*>를 대입할 수 없나요?

왜냐하면 타입 시스템에 구멍을 낼 수 있기 때문입니다. 예를 들자면:
class Apple : public Fruit { void apple_fct(); /* ... */ };
class Orange : public Fruit { /* ... */ }; // Orange에는 apple_fct()가 없음

vector<Apple*> v; // Apple들의 vector

void f(vector<Fruit*>& vf) // 순수하게 Fruit를 조작하는 함수
{
vf.push_back(new Orange); // fruit를 담는 vector에 Orange를 추가함
}

void h()
{
f(v); // error: vector<Apple*>를 vector<Fruit*>로 전달할 수 없음
for (int i=0; i<v.size(); ++i) v[i]->apple_fct();
}

f(v)를 호출하는 것이 허용됐다면, Orange를 Apple라고 가장했을 것입니다.

다른 언어 디자인적인 해결법은 안전하지 않은 변환을 허용하되 그 변환을 동적 검사에 의존하도록 하는 것이었습니다. 이렇게 했었으면 v의 멤버에 접근을 할때마다 실행시간 검사가 필요했을 것이고, v의 마지막 요소를 만나면 예외를 던저야 했을 것입니다.

댓글