프로그래밍/Modern c++

오른값 참조(rvalue reference)

오늘의논리 2023. 3. 6. 22:31
728x90

왼값(lvalue)  vs 오른값(rvalue)

  • lvalue : 단일식을 넘어서 계속 지속되는 개체
  • rvalue : lvalue 아닌 나머지(임시값, 열거형, 람다, i++ )
using namespace std;

class Pet
{};

class Knight
{
public:
	Knight()
	{
		cout << "Knight()" << endl;
	}
	Knight(const Knight& knight)// 복사 생성자
	{
		cout << "const Knight&" << endl;
	}
	~Knight()
	{
		if (_pet) delete _pet;
	}

	//복사 대입 연산자
	void operator=(const Knight& knight)
	{
		cout << "operator=(const Knight&)" << endl;

		//깊은 복사
		_hp = knight._hp;
		if(knight._pet)
			_pet = new Pet(*knight._pet);

	}
	// 이동 대입 연산자
	void operator=(Knight&& knight) noexcept
	{
		cout << "operator=(Knight&&)" << endl;

		//얕은 복사
		_hp = knight._hp;
		_pet = knight._pet;

		knight._pet = nullptr;
	}

	void PrintInfo() const
	{

	}

public:
	int _hp = 100;
	Pet* _pet = nullptr;;
};

void TestKnight_Copy(Knight knight) {}
void TestKnight_LValueRef(Knight& knight) {} // 원본을 넘겨줌
void TestKnight_ConstLValueRef(const Knight& knight) // 원본을 넘겨주지만 수정이나 변경되지 X (readOnly)
{
	knight.PrintInfo(); // const 가 붙으면 const 가 붙은 함수만 사용 가능(readOnly)
}
void TestKnight_RValueRef(Knight&& knight) //원본을 넘겨주는데 변경, 수정 가능 심지어 니가 멋대로 해도되 라는 의미(**이동대상**)
{
	knight._hp = 3;
}


int main()
{
	Knight k1;

	TestKnight_Copy(k1);
	TestKnight_LValueRef(k1);
	//TestKnight_LValueRef(Knight());// 안됨
	TestKnight_ConstLValueRef(Knight()); // 됨
	TestKnight_RValueRef(Knight()); //됨
	TestKnight_RValueRef(static_cast<Knight&&>(k1)); //됨


	Knight k2;
	k2._pet = new Pet();
	k2._hp = 1000;

	//원본은 날려도 된다<< Hint를 주는 쪽에 가깝다!
	Knight k3;
	//k3 = static_cast<Knight&&>(k2);

	k3 = std::move(k2); // 오른 값 참조로 캐스팅
	//std::move 의 본래 이름 후보 중 하나가 rvalue_cast


	return 0;
}
728x90