강의

멘토링

커뮤니티

인프런 커뮤니티 질문&답변

it09kim님의 프로필 이미지
it09kim

작성한 질문수

홍정모의 따라하며 배우는 C++

8.7 this 포인터와 연쇄 호출

레퍼런스 관련 질문입니다.

해결된 질문

작성

·

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 전부 다 별개의 존재들이라는 것을 기억하셔야 합니다.

-

참조에 대한 개념이 자리 잡혀 있어야 이해를 하실 수 있는 부분이라 앞 부분에서 배우셨을 참조 부분을 다시 참고 해보시기를 추천드립니다!

it09kim님의 프로필 이미지
it09kim
질문자

자세하고 친절한 설명 감사드립니다!!

이걸로 5시간 넘게 잡고있었는데 명쾌하게 해결되었어요!!

감사드립니다!! ㅜㅜ

it09kim님의 프로필 이미지
it09kim

작성한 질문수

질문하기