개인의 학습을 목적으로 정리한 글입니다. 이점 참고하고 읽어주세요 ;)
이전 포스팅과 동일한 AutoPtr 헤더파일과 Resource 헤더파일을 가지고 진행합니다.
이번에는 std::move를 사용하는 새로운 예제를 설명해드릴건데요
void print()
{
for (unsigned i = 0; i < m_length; ++i)
std::cout << m_data[i] << " ";
std::cout << std::endl;
}
void setAll(const int& v)
{
for (unsigned i = 0; i < m_length; ++i)
m_data[i] = v;
}
둘 모두 Resource 클래스를 정의한 Resource.h 헤더파일에 구현된 함수들입니다.
단순하게 배열의 값들을 출력하는 print() 함수와,
배열의 값을 입력 값으로 초기화하는 setAll() 함수입니다.
{
AutoPtr<Resource> res1(new Resource(3));
res1.m_ptr->setAll(3);
AutoPtr<Resource> res2(new Resource(5));
res2.m_ptr->setAll(5);
res1.m_ptr->print();
res2.m_ptr->print();
MySwap(res1, res2);
res1.m_ptr->print();
res2.m_ptr->print();
}
이 코드는 main함수에 정의한 새로운 예제입니다.
AutoPtr자료형으로 res1과 res2를 각각 다른 배열의 길이를 주면서 초기화시키고
setAll()함수를 통해 res1에는 3, res2에는 5로 채워줍니다.
그 다음에 모두 print()함수로 호출을 해주고
사전에 정의한 MySwap() 함수로 res1과 res2에 저장된 값을 바꿔줍니다.
MySwap()함수의 코드는 다음과 같습니다.
template<class T>
void MySwap(T& a, T& b)
{
T tmp = a;
a = b;
b = tmp;
}
위에 있는 main 함수를 실행하게 되면
위와 같이 생성자, 소멸자, 복사 생성자, 대입 연산자가 복잡하게 출력됩니다.
이 결과를 통해서는
'L-value'를 사용하는 복사 생성자와 대입 연산자의 경우 Swap 알고리즘에도 꽤 많은 과정이 수반된다..!'정도만 느끼시면 될 것 같습니다.
그럼 이제 'R-value'를 사용하면 어떤 결과가 나오는지 봐야겠죠?
R-value를 사용하는 move-sementics 방법으로 Swap 알고리즘을 사용하려면
template<class T>
void MySwap(T& a, T& b)
{
T tmp{ std::move(a) };
a = std::move(b);
b = std::move(tmp);
}
위의 코드블록과 같이 std::move()를 사용하면 됩니다.
나머지 코드는 건드리지 않고 다시한번 main 함수를 실행하게 되면
Swap 과정에서 복사 생성자를 생성하지 않고 한결 간소화?되어 출력된 결과를 확인할 수 있습니다.
혹시 몰라 말씀드리는데,
std::move()는 사용하려는 클래스에서 사전에 move-sementics의, 그러니까 R-value를 사용하는 복사 생성자, 대입 연산자가 존재할 때에만 사용할 수 있습니다.
※ vector처럼 자주 사용하는 stl에는 자동으로 std::move()를 사용할 수 있게 기능이 구현되어 있다고 하는데, 이건 필요할 때 직접 찾아보면 될 것 같습니다!
'Information Technology > C++' 카테고리의 다른 글
[C++] 입출력 연산자 오버로딩 (0) | 2019.11.15 |
---|---|
[C++] 산술 연산자 오버로딩 (0) | 2019.11.15 |
[C++] std::move(1) (0) | 2019.11.15 |
[C++] 이동 생성자와 이동 대입 (0) | 2019.11.15 |
[C++] 깊은 복사, 얕은 복사, 그리고 대입 연산자 (0) | 2019.11.13 |