제목이 뭐랄까 복잡하지만, 내용을 보니 그정도 까진 아닌거 같다.
다형성이라는 정의를 좀 쉽게 설명하면,
"AAA 클래스를 상속받은 BBB 클래스가 있다.
그리고 AAA 클래스의 객체가 BBB 클래스를 접근하는 것이 가능하다. "
라고 표현 할 수 있겠는데...
아.. 써놓고 보니 쉽지 않은거 같기도 하고--;;
자세한 내용은 다형성에 대해서 "객체 포인터"라는 부분에서 정리를 예전에 해 두었으니 해깔리면
그걸 먼저 보는것이 나을 것 같다.
예제는 2가지정도 존재 하지만,
첫번째 예제만 봐도.
"아!... 위험하네." 싶다.
// 기본 클래스 AAA
class AAA
{
public:
int a;
public:
AAA()
{
a = 0;
}
// AAA 클래스의 연산자 오버로딩
friend ostream& operator<<(ostream& os, const AAA& raaa);
};
ostream& operator<<(ostream& os, const AAA& raaa)
{
os << raaa.a << endl;
return os;
}
// AAA 클래스를 상속받은 BBB 클래스
class BBB : public AAA
{
public:
int b;
public:
BBB()
{
b = 0;
}
};
// 그리고 AAA 클래스의 배열을 출력하는 printAAA
void printAAA( ostream& s, const AAA arr[], int num )
{
for( int i=0; i<num; ++i )
{
s << arr[i].a << endl;
}
}
이런 상황이라고 하였을 때,
쉽게 프로그래머의 의도는, AAA arr[10]; 를 만든 이후,
그 값을 출력하기 위해 printAAA 를 만들었다고 보면 되겠다.
하지만,
void main()
{
AAA arrAAA[10];
for( int i=0; i<10; i++ )
arrAAA[i].a = i;
// 의도한건 이런것인데,,,
printAAA( cout, arrAAA, 10 );
BBB arrBBB[10];
// 이런 상황이 연출 될 수 있다는게 문제.
printAAA( cout, arrBBB, 10 );
// 우리가 의도한 다형성이라는게 이걸 위해 쓰진 않았을 것이다.
}
다음과 같은 상황이 생겼을 때 문제가 발생하는 것이다.
물론 운이 좋게 컴파일러에서 미리 캐치를 해서, 값이 잘 보일 수도 있겠지만.
(실제로 내 컴파일러에서 출력에는 이상이 없긴 했다.)
문제는 delete 라던가, 다른 os나 pc 상황에서 분명 의도하지 않은 결과가 나올 수 있다는 것이다.
AAA의 메모리 크기는 8byte(예상) 라고 했을 때,
BBB의 메모리 크기는 8byte(AAA 클래스의 크기) + 8byte(BBB 클래스의 크기) 라는 것이다.
배열을 +1씩 증가 한다고 했을 때,
8byte씩 삭제 하다 보면,, 나머지 8byte는.. 과연 어디로 증발할지 아무도 모르는 것이다.
물론 BBB라는 클래스가 AAA를 상속받지 않거나, 존재하지 않는다면,
큰 문제가 없을 지도 모른다. 이와 관련되서 추후 항목에 다룬다고 하니, 그 때 다시 한번 확인하여 보자.
'프로그래밍 > More Effective C++' 카테고리의 다른 글
항목6. 증가 및 감소 연산자의 전위 / 후위 형태를 반드시 구분하자. (0) | 2011.04.29 |
---|---|
항목5. 사용자 정의 타입변환 함수에 대한 주의를 놓지 말자 (0) | 2011.04.28 |
항목4. 쓸데 없는 기본 생성자는 그냥 두지 말자. (1) | 2011.04.25 |
항목2. 가능한 C++ 스타일의 캐스트를 즐겨 쓰자. (0) | 2011.04.22 |
항목1. 포인터와 참조자를 구분하자. (2) | 2011.04.22 |