언어/Basic C++

[Basic C++] #25_우측 값 참조, 이동 시맨틱

Hardii2 2022. 5. 14. 20:41

 

[Basic C++] #25_우측 값 참조, 이동 시맨틱

 

C++ 개발에서 까다로운 문법 혹은 특별한 의미를 갖는 부분에 대해 알아보겠습니다.

"전문가를 위한 C"의 10 항목, "C++의 까다롭고 유별난 부분들"에 해당하는 내용입니다.

 


 

Overview

 

  1. 개념
  2. 코드

 

#0. 개념

1. 우측 값 참조?

 

[Basic C++] #24_우측 값 참조, 대입 연산의 좌항과 우항

[Basic C++] #24_우측 값 참조, 대입 연산의 좌항과 우항 C++ 개발에서 까다로운 문법 혹은 특별한 의미를 갖는 부분에 대해 알아보겠습니다. "전문가를 위한 C"의 10 항목, "C++의 까다롭고 유별난 부분

webddevys.tistory.com

 

2. 이동 시맨틱?

class myClass
{
public:
    myClass(myClass&& _tmpMyClass) noexcept;
    myClass& operator=(myClass&& rhs) noexcept;
};

 

Details

 

  • 이동 시맨틱은 이동 생성자와 이동 대입 연산자를 통해 효율성을 도모합니다.
  • 정확히 말해서, 대입 원본 객체가 임시 객체여서 대입 대상으로의 복제 또는 대입이 끝난 후에 원본 객체의 멤버를 null 값으로 초기화시킵니다.
  • 결과적으로, 이동 시맨틱은 얕은 복제를 통해 객체와 객체 간의 메모리 소유권을 이동시키고 댕글링 포인터 혹은 메모리 락의 발생을 방지합니다.
  • 이때, 이동 시맨틱은 이동 생성자와 이동 대입 연산자의 구현이 필수적이며, 
  • 이들은 우측 값 참조형을 파라미터로 사용합니다.
  • 추가적으로, 컴파일러의 익셉션 발생을 방지하기 위해 "noexcept" 키워드도 필요하겠습니다.

 

#1. 코드
// 일반적인 Swap 알고리즘을 활용한 템플릿 함수
Template<typename T>
void swapCopy(T& a, T& b)
{
    T temp(a);
    a = b;
    b = temp;
}

Template<typename T>
void swapMove(T& a, T& b)
{
    // std::move() : 우측 값으로 변환합니다.
    T temp(std::move(a));
    a = std::move(b);
    b = std::move(temp);
}

 

Details

 

  • 자주 사용되는 Swap 알고리즘을 복제의 개념에서 메모리 소유권 이동의 개념으로 재 작성한 코드입니다.
  • 먼저, 기존의 Swap 알고리즘을 간단하게 살펴보자면, 가장 먼저 temp 변수로 a 변수를 복제합니다. 이후의 과정들은 기존의 것들과 동일합니다.
  • 반면에, 이동 시맨틱을 적용한 Swap 알고리즘은 각 변수들을 우측 값 참조를 통해 얕은 복제를 수행합니다.
  • 결국, 얕은 복제를 수행하는 이동 시멘틱 Swap 알고리즘은 복제 과정에서 발생하는 메모리 오버헤드를 방지합니다.