본문 바로가기
프로그래밍/More Effective C++

항목3. 배열과 다형성은 같은 수준으로 놓고 볼 것이 아니다.

by 리뷰하는 (게임)프로그래머_리프TV 2011. 4. 25.


제목이 뭐랄까 복잡하지만, 내용을 보니 그정도 까진 아닌거 같다.

다형성이라는 정의를 좀 쉽게 설명하면,

"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를 상속받지 않거나, 존재하지 않는다면,
큰 문제가 없을 지도 모른다. 이와 관련되서 추후 항목에 다룬다고 하니, 그 때 다시 한번 확인하여 보자.