[C++] 참조 리턴 함수

2022. 2. 9. 18:13Languages/C++

*<씹어먹는 C++>을 보며 공부하여 정리한 글입니다.

 

 

 

오늘은 플레이어(Player) 클래스가 도와주기로 했다!

class Player {
private:
	int hp;
public:
	Player(int hp) : hp(hp) {}
	int GetHP() { return hp; }           // Getter 함수
	int& AccessHP() { return hp; }       // 참조 리턴 함수
	void Show() { std::cout << "HP : " << hp << std::endl; }
};

 

 

Getter 함수

 

  • 함수는 참조나 포인터를 리턴하지 않는 이상, 값을 복사해서 리턴해준다.
  • 값을 복사할 때, 잠깐 임시 객체를 생성해서 리턴 해주고 함수가 끝나면 자동 메모리 반납이 된다.
  • 그렇기에, 참조 변수로 리턴 값을 받으려고 할 경우, 임시 객체에 대한 참조는 생성할 수 없기에 오류가 난다.
Player player(100);
// player.GetHP() = 10;         오류. 임시 객체는 이미 메모리 반납이 이루어져 존재하지 않는다.
// int& ref = player.GetHP();   오류. 임시 객체에 대한 참조자는 생성할 수 없다.

 

 

참조(Reference) 리턴 함수

 

  • 참조를 리턴받기 때문에 접근하여 값 수정이 가능하다.
Player player(100);
player.AccessHP() = 15;    // HP : 15

 

  • 새로운 참조 변수로 받아서 수정할 수도 있다.
Player player(100);
int& refPlayerHP = player.AccessHP();

refPlayerHP = 50;
player.Show();     // HP : 50

 

 

원리를 봤으니, 실전에 적용해보자. 다음과 같이 데미지를 입어 피해를 입는 함수를 하나 정의해줬다.

/*  HP가 0 이하되면 죽는 로직도 있으면 좋겠지만 일단 간단하게 만들었다.  */

class Player {
private:
	int hp;
public:
	Player(int hp) : hp(hp) {}
	int GetHP() { return hp; }
	int& AccessHP() { return hp; }
	void Show() { std::cout << "HP : " << hp << std::endl; }
    	Player& Hitted(int damage);   // 추가
};

Player& Player::Hitted(int damage){   // 추가
    this-> hp -= damage;
    return *this;   // 자기 자신 객체 리턴
}

 

 

자기 자신 객체에 대한 참조를 리턴하기 때문에 값을 복사하는 과정이 없다.

Player player(100);
player.Hitted(10).Hitted(10);
player.Show();   // HP : 80

 

하지만 다음과 같이 참조가 아니라 그냥 객체를 리턴한다면?

Player Player::Hitted(int damage){      // 객체 리턴
    this-> hp -= damage;
    return *this;
}
Player player(100);
player.Hitted(10).Hitted(10);
player.Show();   // HP : 90

 

참조를 리턴하는 게 아니기 때문에 Hitted() 함수는 자기 자신 객체의 복사본을 리턴해준다.

그렇기 때문에 두 번째 Hitted() 함수 호출에서는 첫 번째 Hitted() 함수 호출로 리턴 받은 복사본을 수정한 것.

즉, 두 번째 함수 호출은 엉뚱한 복사본을 수정했기 때문에 원본 객체는 수정되지 않은 것이다.

 

공부하다가 본 내용인데, 알아두지 않으면 나중에 디버그할 때 고생할 것 같아서 이렇게 정리를 했다.

 

 

728x90
반응형