[CPP-Module / ex05: HI BRAIN THIS IS HUMAN 과제]
Brain
class를 만든다. 이 클래스는 identify()
라는 멤버함수를 가져야 한다. 이 함수의 리턴값은 Brain클래스의 메모리 주소이다. (return value: brain’s address in memory, in hexadecimal format ex)"0x194F87EA"
)Human
class를 만든다. 이 클래스는 Brain 클래스의 attribute
를 const
로 가지고 있어야 한다.Now, make it so this code compiles and displays two identical adresses:
int main() {
Human bob;
std::cout << bob.identify() << std::endl;
std::cout << bob.getBrain().identify() << std::endl;
}
둘 다 결국 같은 객체의 주소를 출력하게 만들어야 한다.
const class를 사용해야하는 이유가 뭔지
attribute가 뭔지
attribute란 클래스 내부에 포함되어있는 멤버변수나 함수들을 말한다.
클래스의 메모리 주소값을 어떻게 얻고 반환할 지
this 포인터와 stringstream의 사용방법을 학습했다.
한 클래스 내부에서 다른 클래스의 값을 어떻게 그대로 가져올지
지난 과제때 배운 참조자를 사용한다.
Human클래스가 const Brain클래스를 멤버로 가진다고 하니, 상수 클래스에 대해 알아봤다. 지금까지 const 키워드가 갖고 있던 기능과 비슷한 것 같다. const 객체
가 생성자를 통해 초기화되면 인스턴스의 데이터를 직접 변경하거나, setter 함수를 호출하는 작업 등 멤버변수를 수정하려는 어떠한 시도도 허용되지 않는다.
이번 과제에서는 Brain 인스턴스의 값을 그대로 가져와 출력하는 것이 목표다. 즉, 함수 내부에서 데이터를 직접 변경할 필요가 없을 때에는 const 키워드를 사용해 원본 클래스에 대한 변경을 허용하지 않는 것이 좋은 것이다.
class Human
{
private:
const Brain brain;
public:
std::string identify(void) const;
const Brain& getBrain(void) const;
};
C++에서는 모든 멤버 함수가 자신만의 this 포인터를 가지고 있다. 즉, 멤버함수 내에서는 this
라는 이름의 포인터를 사용할 수 있는데, 해당 멤버함수를 호출한 객체의 주소
를 가리킨다. this는 포인터이므로, 반환할 때는 참조연산자 *
를 사용해야 호출한 객체 그 자체를 반환할 수 있다.
this는 아래 예제와 같은 상황에 유용하게 쓰일 수 있다. 클래스 내의 함수의 매개변수가 멤버변수의 이름과 동일할 때, this를 사용하지 않으면 멤버변수 num을 참조하지 못하고 인수로 받은 num의 값밖에 참조할 수 없다. 아래처럼 ->
연산자와 함께 this를 사용하면 인스턴스에 접근할 수 있을 것이다.
class ThisClass {
private:
int num;
public:
void ThisFunc(int num) {
this->num = 207;
num = 105;
}
...
};
어쨌든 이제 this를 사용하면 인스턴스의 주소값을 얻을 수 있다는 걸 알았으니, identify(void)
함수를 잘 정의해주기만 하면 될 것 같다.
identify(void)
함수 내부에서 this를 출력해보면 0x7ffeeca56608
과 같은 Brain객체의 메모리 주소가 나오는 것을 확인했다. 처음에는 메모리 주소가 어떤 자료형이든 string으로만 가져오면 될 것이라고 생각해 *this.str()
와 같이 반환해보려고 했다. 그런데 이 때의 this는 Brain 객체 그 자체를 의미하고 있기 때문에, .str()
함수가 Brain의 멤버함수로 인식돼서 에러가 발생했다.
결국 str() 함수를 사용하기 위해서는, this통해 접근할 수 있는 객체의 주소값을 어딘가에 잠깐 저장해둬야 한다. 이때 필요한 것이 스트림(stream)
이다. CPP 첫 과제에서 스트림에 대해 배웠을 때, 어떤 장치와 장치 중간의 매개체 같은 역할을 해준다고 했었다. 즉, 주소값이 하나의 스트림이 되어야 한다.
CPP의 <sstream>
에는 문자열 스트림(std::stringstream
)이 정의되어 있다. 그 중에서도 출력 문자열스트림(std::ostringstream
)을 이용한다. this를 마치 어떤 공간에 잠깐 저장해뒀다가 보내주는 것이라고 생각하면 된다.
std::ostringstream ss;
ss << this;
this의 값을 문자열 스트림에 출력했다. 이 과정에서 자동으로 class형에서 문자열로의 변환이 있을 것이다. 그리고 str() 함수로 문자열 스트림에 쓰여 있는 값을 불러오기만 하면 된다.
ss.str()