인프런 커뮤니티 질문&답변
레퍼런스 관련 질문입니다.
해결된 질문
작성
·
192
0
안녕하세요
class Calc
{
private:
int m_value;
public:
Calc(int init_value)
: m_value(init_value)
{}
Calc& add(int value) { m_value += value; return *this; }
Calc& sub(int value) { m_value -= value; return *this; }
Calc& mult(int value) { m_value *= value; return *this; }
Calc& div(int value) { m_value /= value; return *this; }
void print()
{
cout << m_value << endl;
}
};
int main()
{
//Simple s1(1), s2(2);
//s1.setID(2);
//s2.setID(4);
//cout << &s1 << " " << &s2 << endl;
Calc cal(10);
cal.add(10).sub(1).mult(2).print();
//cal.add(10);
//cal.sub(1);
//cal.mult(2);
//cal.print();
Calc &temp1 = cal.add(10);
cout << &temp1 << endl;
temp1.print();
Calc &temp2 = temp1.sub(1);
cout << &temp2 << endl;
temp2.print();
Calc &temp3 = temp2.mult(2);
cout << &temp3 << endl;
temp3.print();
위에 코드가 원본 코드입니다.
저기서
Calc 함수 생성자 내에 add,sub,mult 함수의 리턴값을
레퍼런스가 아닌 그냥 Calc로
public:
Calc(int init_value)
: m_value(init_value)
{}
Calc add(int value) { m_value += value; return *this; }
Calc sub(int value) { m_value -= value; return *this; }
Calc mult(int value) { m_value *= value; return *this; }
Calc div(int value) { m_value /= value; return *this; }
질문
이렇게 받았을때 리턴값이 Main 내에 Calc temp1 = cal.add(10);
했을 때 38에서 +10이 되어서 48이 되어야 할 것 같은데 30이 나오는데 그 이유가 궁금합니다.
그뒤에는 -1 *2 된 값이 나와서
이전 값이 30이라고 가정한다면 때 각 각
Calc temp2 = temp1.sub(1);
Calc temp3 = temp2.mult(2); 의 리턴 값으로 29, 58로 나옵니다.
유튜브로 실리콘밸리에서 생활하시는 영상 잘 보고 있습니다 바쁘신 와중에도 답변 해주셔서 감사합니다.
답변 1
10
강의 코드대로 참조로 했을 때, 질문자님처럼 참조 다 떼고 값으로 했을 때의 과정을 적어보겠습니다. 한번 비교해보세요!
& 참조일 때
Calc cal(10);
cal.add(10).sub(1).mult(2).print();
cal 객체 -> m_value = 10
cal.add(10) 로 인하여 cal 객체의 m_value 가 20 이 된 후 이 cal 객체 "원본"을 리턴 (즉, 원본 참조)
연쇄 호출 : 리턴된 cal 객체 "원본"에서 sub(1) 호출로 인하여 cal 객체의 m_value 가 19 이 된 후 이 cal 객체 "원본"을 리턴 (즉, 원본 참조)
연쇄 호출 : 리턴된 cal 객체 "원본"에서 mult(2) 호출로 인하여 cal 객체의 m_value 가 38 이 된 후 이 cal 객체 "원본"을 리턴 (즉, 원본 참조)
연쇄 호출 : 리턴된 cal 객체 "원본"에서 print() 호출로 인하여 cal 객체의 m_value 인 38 출력
Calc& temp1 = cal.add(10);
temp1 은 Calc& 참조타입입니다. 그러니 cal.add 가 리턴하는 객체 (*this 이니 cal 객체 본인이죠) 그 자체를 참조하게 됩니다. 즉, temp1 과 cal 은 동일한 객체를 가리키게 됩니다. (m_value 가 38이 된 그 객체) 즉 temp1 은 곧 cal 이나 마찬가지인거에요. 그러니 temp1.sub(1) 은 곧 cal.sub(1) 이나 마찬가지이고, temp2.mult(2) 도 곧 cal.mult(2) 나 마찬가지이게 된 것입니다. temp1,2,3 이 cal 객체 그 자체를 "참조" 하던 것을 생각해보면 왜 48 47 97 가 출력됏는지 이해하실 겁니다.
참조 아닐 때
Calc cal(10);
cal.add(10).sub(1).mult(2).print();
cal 객체 -> m_value = 10
cal.add(10) 로 인하여 cal 객체의 m_value 가 20 이 된 후 이 cal 객체를 복사한 "사본"을 리턴 (그냥 Calc 리턴 타입이기 때문에 이는 *this 를 리턴한거더라도 cal 원본 그 자체의 참조가 아닌 cal 의 사본인 임시 객체를 리턴하는 것입니다.)
연쇄 호출 : 리턴된 m_value = 20 상태의 "임시 객체"에서 sub(1) 호출로 인하여 "임시 객체"의 m_value 가 19 이 된 후 이 임시 객체를 복사한 "사본"을 리턴 (원본인 cal 객체는 m_value = 20 상태에서 더 이상 변하지 않았습니다. 빼기 1 이 된건 사본 임시 객체의 m_value 일 뿐입니다.)
연쇄 호출 : 리턴된 m_value = 19 상태의 "임시 객체"에서 mult(2) 호출로 인하여 "임시 객체"의 m_value 가 38 이 된 후 이 임시 객체를 복사한 "사본"을 리턴 (원본인 cal 객체는 m_value = 20 상태에서 더 이상 변하지 않았습니다. 곱하기 2 가 된건 사본 임시 객체의 m_value 일 뿐입니다.)
연쇄 호출 : 리턴된 m_value = 38 상태의 "임시 객체"에서 print() 호출로 인하여 "임시 객체"의 m_value (38) 가 출력됨
즉, 여기까지 과정으로 38이 출력되게 되었으나, 원본인 calc 은 원본에서 호출한 cal.add(10) 에서 변경된 m_value = 20 상태에선 변함이 없습니다. 즉, 원본은 20 인거에요. sub(1).mult(2).print() 는 사본인 임시객체에서 호출된거구요!
Calc temp1 = cal.add(10);
이 과정은 cal.add(10) 가 리턴한 임시 객체를 복사하여 temp1 이 담게 된 경우입니다. temp1 은 그냥 Calc 타입의 변수일 뿐입니다. 즉, 앞에서 참조 붙였을 때와는 다르게 temp1 과 cal 은 전혀 다른 별개의 객체가 되는 것입니다. (복사만 된 사본) cal 의 m_value 는 20 이라고 말씀드렸습니다. 그러니 add(10) 으로 30이 된 후 temp1 은 이 m_value 가 30이 된 모습의 cal 객체의 사본이 되므로 30을 출력하는 것입니다.
temp2 는 m_value 가 30 인 temp1 에서 호출한 sub(1) 리턴 객체의 사본이니 29 가 되는 것이구요
마찬가지로 temp3 은 m_value 가 58 인 temp2 에서 호출한 mult(2) 리턴 객체의 사본이니 58 이 되는 것입니다.
질문자님의 코드일 땐 참조를 사용한 강의 코드와는 다르게 cal, temp1, temp2, temp3 전부 다 별개의 존재들이라는 것을 기억하셔야 합니다.
-
참조에 대한 개념이 자리 잡혀 있어야 이해를 하실 수 있는 부분이라 앞 부분에서 배우셨을 참조 부분을 다시 참고 해보시기를 추천드립니다!






자세하고 친절한 설명 감사드립니다!!
이걸로 5시간 넘게 잡고있었는데 명쾌하게 해결되었어요!!
감사드립니다!! ㅜㅜ