아래 코드의 출력값을 쓰시오.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
|
#include <iostream>
using namespace std;
class Myclass {
public:
Myclass():num(cnt++),ch('\0'){}
void Check(Myclass* ptr) {
if (ptr + num == this) {
cout << num << endl;
}
}
static int cnt;
private:
int num;
char ch;
};
int Myclass::cnt = 0;
int main() {
Myclass obj[5];
cout << "Test #1 : " << endl;
for (int i = 0; i < 5; i++) {
obj[i].Check(obj);
}
cout << "Test #2 : " << endl;
for (Myclass& i : obj) {
i.Check(obj);
}
cout << "cnt= " << Myclass::cnt << endl;
}
|
cs |
코드를 하나하나 뜯어보자.
7번째 줄에
Myclass():num(cnt++)
--> 객체가 하나씩 생길때 마다 cnt가 1씩 증가하는걸 의미한다.
cnt는 후위증가 연산자라서 첫번째로 객체가 만들어지고 cnt가 1이 증가하기에 obj[0]의 cnt는 0이다.
여기서 num과 cnt가 같다고 생각해 줄 수 있다. num이 0일때 cnt도 0 이런식이기 때문에
24번째 줄 Myclass obj[5]; 은 obj라는 배열 한칸 한칸에 Myclass 라는 객체가 들어가는 형식으로 이루어져 있다.
Test1번을 살펴보자
28번째 줄에 obj[i].Check(obj); 를 보면 obj[i].Check(&obj[0])이라고 생각할 수 있다.
그래서 9번째 줄로 올라와서 void Check(Myclass* ptr) 의 ptr에는 obj[0]의 주소값이 고정적으로
들어가게된다.
10번째 줄에 ptr + num 을 보면 ptr+num은 결국에 &ptr[num]이 된다.
근데 생각해보면 ptr=&obj[0]=obj이기 때문에 ptr도 obj이다.
그래서 ptr+num=&obj[num]으로 생각해 줄 수 있다.
ptr + num == this 를 보면 결국 this도 자기가 속해있는 객체를 가리키기 때문에
if(ptr+num==this)는 항상 성립하게 된다.
예를 들어 obj[i].Check(obj)에서 i가 3일 때 num도 3일거고
ptr+num은 &obj[3] 일거다 이때 this도 당연히 &obj[3]을 가리키기 때문에 if문은 항상 성립한다
그래서 결국 출력값은
0
1
2
3
4
가 나온다.
Test 2번을 살펴보자
for (Myclass& i : obj) 를 보면 i도 레퍼런스 변수 이기 때문에 얘도 배열의 한칸 한칸을 가리키고 있을 것이다.
결국에 i도 obj[i]와 같다고 보면된다.
얘도 출력값은
0
1
2
3
4
가 나온다.
cnt는 객체가 한번 생성될때 마다 1씩 증가하기 때문에 결국 객체가 5개 생성되어 cnt 값은 5가 되는 것을 알 수 있다. 그럼 여기서 의문이 생기는게 있는데 cnt가 후위증가 연산자이기 때문에 cnt값도 결국에 4가 되지 않아야 하는 의문이 들 수 있다(나는 그런 의문이 들었다)
하지만 잘 생각해보면
cnt가 1이 증가 되고 그 값이 cnt에 저장되는 거기 때문에 cnt만 출력하면 얘는 5가 맞다.
하지만 객체 상에서는 다르다. 객체가 생성되는 시점과 cnt가 1만큼 증가하는 시점이 다르다.
객체가 생성되고 -> 그 다음에 cnt가 1 증가되어서 증가된 값이 cnt에 저장되는 거기 때문에
얘를 들어 obj[0]이 생성되면 생성된 타이밍에 cnt는 0 -> 그후 cnt 값이 1만큼 증가 -> 증가된 값이 cnt에 저장
이런 순이기때문에 달랐던 것이다.
++) 22/07/05 추가
쉽게 말해서 this는 obj[i]를 말한다. 그냥 자기 자신
obj 배열자체를 Check에 매개변수로 넘겨줘서 obj+num==obj[i]이면 값을 출력하는데
여기서 중요한것은 num은 cnt인데 사실상 cnt랑 i가 같다. 그래서 조건문이 항상 참이 된다!!
'C++ > 기초(두들낙서)' 카테고리의 다른 글
[C++기초] 깊은복사와 얕은 복사 ,복사생성자 (0) | 2022.01.15 |
---|---|
[C++기초] 동적할당 (0) | 2022.01.15 |
[C++기초] 연산자 오버로딩 (0) | 2022.01.14 |
[C++ 기초] 멤버 메서드 활용 (0) | 2022.01.14 |
[C++기초] 상수형 매개변수와 상수형 메서드 (0) | 2022.01.14 |
댓글