일단, 따로 객체를 생성해서 인자로 넘기느냐, 아니면 내부적으로
생성하느냐는 큰 차이는 없어보입니다. code의 추상화 측면을
보자면 내부에서 생성하는 방식이 더 좋은 것 같긴 합니다;
그건 제쳐두고, 저는 그 객체를 받아 terrain을 생성하는 부분에
초점을 맞춰서 생각해보겠습니다. 윗분들이 몇가지 방법을 제시하셨는데요,
모두 나름대로 장단점이 있습니다만...
일단 isValid... 식의 검사는 좋지 않다고 봅니다. 왜냐면
그 함수를 호출해야 한다는 것은 <resource 획득은 초기화>라는
좋은 개념에 어긋납니다. 객체는 생성된 순간, 사용 가능해야 합니다.
또 검사를 빼먹는 것은 쉬운 일이고,
그렇다면 bug의 가능성은 언제나 도사리고 있습니다. 그리고
만약 그 객체를 사용하는 사람이 검사를 빼먹을 경우를 대비해서,
그 객체 내부의 함수에서 현재 객체의 상태가 특정 조건을 만족하는지
검사를 해주는 방법도 있습니다. 하지만 code가 지저분해질 뿐만
아니라 근본적인 문제를 단지 객체 외부에서 내부로 옮겼을 뿐입니다.
NULL 검사는 예외 처리에 드는 부하도 없고, 실제로 많이
사용되는 방법입니다. 하지만 이것 역시 검사를 빼먹을 수 있다는
점에서 잠재적인 위험이 있습니다. 물론 검사를 빼먹어도 NULL pointer를
역참조할 때 오류가 발생하므로 어떻게든 문제점은 발견되지만, 그 원인의
정확한 위치를 파악하기 힘들다는 문제가 있습니다. 또 깊은
함수 호출이 일어날 경우, 함수들이 일일이 성공/실패 여부를 되돌려야
한다는 문제도 있습니다.
예외 처리는 run-time 강제성이 있다는 점에서 좋습니다.
단점은 예외가 발생했을 때 완벽히 복구(예외를 처리한 후 계속
실행가능하게 함)되게 하는 것은 어렵다는 것과, 복구 시에 부하가
크다는 것입니다. 예외 발생시 정확한 복구가 어렵다는 것은
Exceptional C++, More Exceptional C++ 책을 보면 아실 것입니다.
예외 복구에 안전한 code를 만드는 건 배보다 배꼽이 더 커집니다;
비록 예외 복구가 어렵다해도 결론은...실행시에 부하가 많이 걸릴
정도로 잦은 복구가 필요한 곳에는 NULL 비교와 같은 방식을 쓰고,
그 외에는 최대한 예외 처리를 이용하는 게 좋은 것 같습니다.
하지만...아직도 C만을 고집하는 사람이 많듯이 자기 편한대로
쓰는 것이 좋을지도...

쉬운 것은 올바르다.