CPP01 평가를 진행했다. 이번 평가를 통해 나에 대해 느꼈던 2가지가 있다.
당황한 상황에서도 생각할 줄 알게 되었구나.
const 함수, const 반환값, const 매개변수에 대해 머리로는 알지만 남에게 설명하는 연습이 부족했다. 예전 같았으면 머리속이 하얗게 됐을텐데, 차근차근 생각하며 코드리뷰를 진행해서 평가자를 이해시켰다.
C++ 공부를 잘해나가고 있구나.
평가를 진행하며, 좋은 설명을 들었다는 이야기를 들었다. C 를 공부 할 때는 공부 방식이 항상 아쉽다는 생각이 있었는데, CPP 공부는 나름 괜찮게 하고 있다는 생각이 들었다.
얼마 전 이노콘에서 학장 대행 업무 중이신 나연묵 학장님이 42서울은 배우는 방법을 배우는 곳이라는 표현을 했다. 인상 깊었던 말이었는데, C 프로젝트할 때와 지금을 비교해보면, 배우는 방법을 잘 배워가고 있는 것 같다.
C 에서는 malloc 과 free 를 사용한다. 할당할 크기를 파악해서 sizeof(자료형) * 크기
의 방식으로 할당해야하는데, C++ 에서는 new
만 사용하면 알아서 할당해주어 번거로움을 없애준다. 해제할 때도 편하다. 예를 들어 배열을 해제한다면, C 에서는 메모리 하나 하나 이동하며 해제 후 전체를 해제해야하는데 C++에서는 delete [] 변수명
으로 해제할 수 있다.
반환값을 const 로 하는 이유는 명확하다. 객체 지향 프로그래밍을 해야하기 때문이다. 즉, 객체 멤버 변수 조작을 객체 멤버 함수를 통해서만 가능하게 하기 위해서이다.
const 이야기를 하기 전에 예시를 통해 const가 없을 때 발생하는 아쉬운 점을 알아보자.
main 문에는 club 이라는 무기 객체를 만들었고, HumanA 객체 Bob 멤버에 club 대입했다. 그후 attack()이라는 멤버 함수를 이용해서, 공격했다는 문구를 출력한다. (* 이미지 참고!)
main(void)
{
...
Weapon club = Weapon("crude spiked club");
HumanA bob("Bob", club);
bob.attack();
...
}
Bob 이 갖고 있는 무기를 다른 무기로 바꾸고 싶을 때 어떻게 해야할까?
두가지 방법이 있다.
외부에서 객체를 조작
객체가 자신을 조작
main(void)
{
...
Weapon club = Weapon("crude spiked club");
HumanA bob("Bob", club);
bob.attack();
club.getType() = "gun"; // main 문에서 객체를 조작
bob.attack();
...
}
하하하... 무기가 바뀌긴 한다. 하지만,,, 객체 지향의 특성을 전혀 활용하지 못한다. 이럴거면 C 로 돌아가...!! 객체 지향 프로그래밍에서는 객체의 자유도가 높다는 특징이 있다. 즉, 의존성이 낮아야한다. 하지만 main 문에서 객체 멤버 변수를 직접 수정한다면,,, 이걸 객체 지향다운 프로그래밍이라고 할 수 있을까?!
main(void)
{
...
Weapon club = Weapon("crude spiked club");
HumanA bob("Bob", club);
bob.attack();
club.setType("gun"); // 객체가 자신의 멤버 함수를 통해 직접 자신을 조작
bob.attack();
...
}
객체 지향답게 바꾸기 위해 세터(setter)를 사용한다. 결과는 같지만, main 문이 아닌, 객체가 자신이 갖고 있는 멤버 함수를 통해 자신의 무기를 바꾸는 모습이다..!! 이전보다 객체 지향다워졌다.
세터만 잘 사용해도 객체 지향다운 프로그래밍을 할 수 있다. 하지만 개발자가 신경을 덜 쓰게 할 수 있게 하는 방법이 있다면 좋을 것 같다. 이때 const 를 사용한다. const 를 사용하면, 외부에서 객체를 조작하려고 할 때 에러를 출력하여 컴파일을 막을 수 있다.
이전에 있던 setter 의 신텍스는 다음과 같다. std::string& getType(void);
const 선언이 없기 때문에 반환 후에 조작이 자유롭다. 그래서 club.getType() = "gun"; // main 문에서 객체를 조작
이 가능하다.
const std::string& getType(void);
로 반환값에 const 를 추가하면, 상수로 반환하기 때문에 컴파일 시 에러가 발생한다.!!
대신 setType 을 사용할 수 있다. 이런 식으로 const 반환을 함으로써 외부에서 객체를 조작하는 것을 방지할 수 있다.
함수도 상수화하자. const std::string& getType(void) const;
함수 내부에서 객체를 조작하지 않으면 const 를 붙여주자. getType 은 객체를 조작하지 않기 때문에 const를 붙일 수 있다. 반대로 setType 에 const 를 붙이면 에러가 발생한다.
const 어렵지만... 평가를 통해 조금 더 알게된 느낌이다... 앞으로 프로젝트 진행하면서 더 알아가자.