#include <iostream>
using namespace std;
//변경 가능한 참조형 변수라는 힌트를 줌
#define OUT
//int형 3개 총 12 바이트
struct StatInfo {
int hp; //+0
int attack; //+4
int defence; //+8
};
void CreateMonster(StatInfo* info) {
info->hp = 100;
info->attack = 10;
info->defence = 5;
}
//특정 조건을 만족하는 몬스터를 찾는 경우
StatInfo* FindMonster() {
//못찾았을 경우 nullptr을 반환
return nullptr;
}
//주소 전달 방식
void PrintInfoByCopy(const StatInfo* const info) {
cout << "HP: " << info->hp << endl;
cout << "attack: " << info->attack << endl;
cout << "defence: " << info->defence << endl;
}
//참조 전달 방식
void PrintInfoByRef(const StatInfo& const info) {
cout << "HP: " << info.hp << endl;
cout << "attack: " << info.attack << endl;
cout << "defence: " << info.defence << endl;
}
void ChangeInfo(OUT StatInfo& info) {
info.hp = 1000;
}
//포인터 문법의 const 사용
//별 뒤에 붙일 경우
//StatInfo* const info
//info라는 바구니의 내용물(주소)을 바꿀 수 없다.
//info는 주소값을 갖는 바구니 -> 이 주소값이 고정이다.
//ex) info=&globalInfo => 불가
//별 앞에 붙일 경우
//const StatInfo* info
//info라는 바구니의 내용물이 가리키는 바구니의 내용물을 바꿀 수 없다.
//ex) info->hp=200 => 불가
int main()
{
StatInfo info;
//포인터 vs 참조
//성능 : 똑같음(어셈블리어로 보면 같다)
//편의성 : 참조 승!
//편의성이 좋다는 것이 꼭 장점만은 아니다
//왜why? 포인터는 주소를 넘기니 확실하게 원본을 넘긴다는 힌트를 줌
//참조는 참조시 변수의 이름을 명시하므로 자연스럽게 모르고 지나칠 위험이 있다.
//const를 붙여 미연에 방지하자
//초기와 여부
//참조 타입은 바구니의 2번째 이름(별명)
//-> 참조하는 대상이 없으면 안된다. 초기화가 필수적
//반면 포인터는 그냥 어떤 주소라는 의미
//->대상이 없어도 괜츈
//StatInfo* Pointer=nullptr 로 표현(Null포인터)
//참조 타입은 nullptr 개념이 없다.
//언리얼에서는 ref도 애용
//nullptr을 사용해야 할 경우는 포인터 사용
//readonly의 경우 const를 사용한 ref가 낫다
//그 외 일반적으로는 ref애용 (명시적으로 Define OUT을 활용해 호출할 때 OUT을 붙인다)
//포인터로 사용하던걸 참조로 넘겨줄 경우
//참조는 변수를 직접 받으므로 *를 붙여서 사용
//참조로 사용하던걸 포인터로 넘겨줄 경우
//포인터는 주소를 받으므로 &를 붙여서 사용.
CreateMonster(&info);
ChangeInfo(OUT info);
PrintInfoByCopy(&info);
PrintInfoByRef(info); //주소값 전달 없이 변수를 전달하면 알아서 주소값 참조
return 0;
}