---
description: this와 stringstream 을 활용해 인스턴스의 주소값을 문자열로 얻을 수 있다.
---

# \[CPP-01] this 포인터와 문자열 스트림(stringstream)

**\[CPP-Module / ex05: HI BRAIN THIS IS HUMAN 과제]**&#x20;

1. `Brain` class를 만든다. 이 클래스는 `identify()`라는 멤버함수를 가져야 한다. 이 함수의 리턴값은 Brain클래스의 메모리 주소이다. (return value: brain’s address in memory, in hexadecimal format ex)`"0x194F87EA"`)
2. `Human` class를 만든다. 이 클래스는 Brain 클래스의 `attribute`를 `const`로 가지고 있어야 한다.

Now, make it so this code compiles and displays two identical adresses:

```cpp
int main() {
  Human bob;
  std::cout << bob.identify() << std::endl;
  std::cout << bob.getBrain().identify() << std::endl;
}
```

둘 다 결국 같은 객체의 주소를 출력하게 만들어야 한다.

### 고민한 지점

1. const class를 사용해야하는 이유가 뭔지
2.  attribute가 뭔지

    > attribute란 클래스 내부에 포함되어있는 멤버변수나 함수들을 말한다.
3.  클래스의 메모리 주소값을 어떻게 얻고 반환할 지

    > this 포인터와 stringstream의 사용방법을 학습했다.
4.  한 클래스 내부에서 다른 클래스의 값을 어떻게 그대로 가져올지

    > 지난 과제때 배운 참조자를 사용한다.

## 1. const 클래스

Human클래스가 const Brain클래스를 멤버로 가진다고 하니, 상수 클래스에 대해 알아봤다. 지금까지 const 키워드가 갖고 있던 기능과 비슷한 것 같다. `const 객체`가 생성자를 통해 초기화되면 인스턴스의 데이터를 직접 변경하거나, setter 함수를 호출하는 작업 등 **멤버변수를 수정하려는 어떠한 시도도 허용되지 않는다.**

이번 과제에서는 Brain 인스턴스의 값을 그대로 가져와 출력하는 것이 목표다. 즉, 함수 내부에서 데이터를 직접 변경할 필요가 없을 때에는 **const 키워드를 사용해 원본 클래스에 대한 변경을 허용하지 않는 것이 좋은 것**이다.

```cpp
class Human
{
private:
    const Brain brain;

public:
    std::string identify(void) const;
    const Brain& getBrain(void) const;
};
```

## 2. this 포인터 활용

C++에서는 모든 멤버 함수가 자신만의 this 포인터를 가지고 있다. 즉, 멤버함수 내에서는 `this`라는 이름의 포인터를 사용할 수 있는데, **해당 멤버함수를 호출한 객체의 `주소`를 가리킨다.** this는 포인터이므로, 반환할 때는 참조연산자 `*`를 사용해야 호출한 객체 그 자체를 반환할 수 있다.

this는 아래 예제와 같은 상황에 유용하게 쓰일 수 있다. 클래스 내의 함수의 매개변수가 멤버변수의 이름과 동일할 때, this를 사용하지 않으면 멤버변수 num을 참조하지 못하고 인수로 받은 num의 값밖에 참조할 수 없다. 아래처럼 `->` 연산자와 함께 this를 사용하면 인스턴스에 접근할 수 있을 것이다.

```cpp
class ThisClass {
private:
    int num;
public:
    void ThisFunc(int num) {
        this->num = 207;
        num = 105;
    }
    ...
};
```

어쨌든 이제 this를 사용하면 인스턴스의 주소값을 얻을 수 있다는 걸 알았으니, `identify(void)` 함수를 잘 정의해주기만 하면 될 것 같다.

## 3. stringstream: 주소값 문자열로 변환하기

`identify(void)` 함수 내부에서 this를 출력해보면 `0x7ffeeca56608`과 같은 Brain객체의 메모리 주소가 나오는 것을 확인했다. 처음에는 메모리 주소가 어떤 자료형이든 string으로만 가져오면 될 것이라고 생각해 `*this.str()` 와 같이 반환해보려고 했다. 그런데 이 때의 this는 Brain 객체 그 자체를 의미하고 있기 때문에, `.str()` 함수가 Brain의 멤버함수로 인식돼서 에러가 발생했다.

결국 str() 함수를 사용하기 위해서는, this통해 접근할 수 있는 **객체의 주소값을 어딘가에 잠깐 저장**해둬야 한다. 이때 필요한 것이 `스트림(stream)`이다. CPP 첫 과제에서 스트림에 대해 배웠을 때, 어떤 장치와 장치 중간의 매개체 같은 역할을 해준다고 했었다. 즉, **주소값이 하나의 스트림이 되어야 한다.**

CPP의 `<sstream>`에는 문자열 스트림(`std::stringstream`)이 정의되어 있다. 그 중에서도 출력 문자열스트림(`std::ostringstream`)을 이용한다. this를 마치 어떤 공간에 잠깐 저장해뒀다가 보내주는 것이라고 생각하면 된다.

```cpp
std::ostringstream ss;
ss << this;
```

this의 값을 문자열 스트림에 출력했다. 이 과정에서 자동으로 class형에서 문자열로의 변환이 있을 것이다. 그리고 str() 함수로 문자열 스트림에 쓰여 있는 값을 불러오기만 하면 된다.

```cpp
ss.str()
```
