프로그래밍/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