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

항목4. 쓸데 없는 기본 생성자는 그냥 두지 말자.

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


차암.. 이 부분은 읽으면 읽을 수록,
"아. 어쩌라고 ㅋㅋ"
라는 말이 절로 나온다.

쉽게 풀어 설명하면,

class AAA
{
public:
	int id;

	AAA( int _id )
	{
		id = _id;
	}
};​


다음과 같은 클래스가 있다고 치자.
사용자는 무언가 생성할때 ID를 같이 초기화 하고 싶은것이다.
각 id는 중복 되서는 안되고, 고유의 id를 가지고 있다고 치자.
그렇기 때문에 생성할 때 id를 넣어 주는 식의 방법을 채택 하였는데,
문제는 이거다.

void main()
{
	// 잘 된다.
	AAA a(10);

	// 이런식으로 하면 잘 된다.
	AAA arra[] = {
		AAA(0),
		AAA(1),
		AAA(2),
		AAA(3),
	};

	// 여기서 부터가 문제
	AAA aaa;
	// 기본 생성자가 없어서 생성이 불가능(컴파일 단계 오류)
	AAA arr[10];

	// 마찬가지 이유로 생성이 불가능하다.
	AAA* pa = new AAA[10];
}​


책에서는 여러 가지 방법들이 보여지는데,
이래저래 쭉 읽다 보면 결론은,
그냥 내비 둬라(?) ... 라는 결론이 나오게 되는데,
해결책의 첫번째에는, 생성을 객체의 배열을 포인터로써 생성한다는 방법인데,
사실 이 부분도, 결과적으론 최종 생성할때 생성자에 인자를 넣어 주는 방식이고,
(어찌 보면 괜히 메모리만 더 먹는거 같기도 하다.)
다음 부분은 기본 생성자를 생성하여 문제를 직접 해결하고,
추후에 값이 올바른지 그렇지 않은지 예외 조건을 넣으라는 것이다.
하지만 그 부분은 포퍼먼스가 많이 떨어지고, 다른 작업자가, 그런 예외 처리를 해주지 않을 수도 있다는 것이 단점,
근데 솔직히 내가 생각 했을 때 가장 편한건,
기본생성자를 하나 넣어주고, static이나, 전역 변수를 하나 잡아주어,
중복을 피하는 식으로 무작정 데이터를 삽입하는게 어떤가 싶은데,
내 예상 해결책은 다음과 같다.

#include <iostream>

using namespace std;

int g_id = 0;

class AAA
{
public:
	int id;
// 다음 처럼 변경하였다.
	AAA()
	{
		id = g_id;
		++g_id;
	}
	AAA( int _id )
	{
		id = _id;
		g_id = _id;
	}
};​


하지만 이 부분에 문제점은 여전히 존재한다.
사실상, 어떤 값이 어떻게 들어 가게 될지 예측을 못한다는 것이다.
순차적으로 들어갈 수도 있고, 중간에 뛰엄뛰엄 들어갈 수도 있고..
의도한다면 중복된 값또한 넣을 수 있다는 것이다.

이 부분에 대해선 사실 정해진 답이 존재 한다기 보단,
생성자에 대해서 정확히 파악하고,
생길 수 있는 문제에 대해서 미리 한번 생각해 보라...
라는것을 말하고 있다고 생각한다.