이동 생성자 / 이동 대입 연산자

headkio·2020년 9월 19일
0

C++

목록 보기
29/35
post-thumbnail

값의 분류

lvalue

  • 주소가 있음
  • 이름이 있는 변수
  • const 변수
  • 배열 변수
  • 비트 필두
  • 구조체
  • 클래스
    -> 지금껏 봐왔던 일반적인 변수

rvalue

  • 일시적인 값

rvalue 참조

&& -> rvalue 참조 연산자
& -> lvalue 참조 연산자

int num = 10;
int&& rNum1 = num; // ERROR !!, num은 lvalue
int&& rNum2 = 10; // OK, 10은 rvalue
float&& rAvg = CalAvg(); // Ok, CalAvg()는 rvalue

move()
lvalue를 rvalue로 변환하여 반환하는 함수였다.

이동 생성자

class MyString
{
  public: 
    MyString(MyString&& other); // 이동 생성자 폼
}

MyString::MyString(MyString&& other) 
  : mString(other.mString)
  , mSize(other.mSize)
{
  other.mString = nullptr;
  other.mSize = 0;
}

int main() 
{
  MyString student1("Lulu");
  MyString student2(std::move(student1));
}

student2로 데이터를 모두 넘기고 student1은 소멸한다.
값을 복사하기 위해 메모리 재할당을 하지 않고
참조 값을 사용해 소유권을 넘긴다.
복사 생성자보다 빠르다.

이동 대입 연산자

class MyString
{
  public:
    MyString(MyString&& other); // 이동 생성자 폼
}

MyString& MyString::operator=(MyString&& other) 
{
  if (this != &other) 
  {
    delete[] mString;
    
    mString = other.mString;
    mSize = othermSize;
    
    other.mString = nullptr;
    other.mSize = 0;
  }
  
  return *this;
}

int main() 
{
  MyString student1("Lulu");
  MyString student2("Teemo");
  
  student2 = std::move(student1);
}

student2가 원래 가지고 있던 메모리를 해제해주고
student1의 소유권을 가져온다.

C++11 이후 이동 생성자 / 이동 대입 연산자가 자동 생성된다.
추가로 구현할 필요 없다.

Best Practice

  • NRVO(Named RValue Optimization)은 컴파일러가 해주는 반환 값 최적화(Return Value Optimization)를 깨트린다. -> 더 느려질 수 있다.
  • 기본적으로 그냥 개체를 반환하자.
  • 더 빨라진다고 입증된 경우에만 rvalue를 쓰자.
  • rvalue는 unique_ptr에 사용된 것으로 만족하자.
profile
돌아서서 잊지말고, 잘 적어 놓자

0개의 댓글