C++/Library
2021. 3. 24. 10:45
std::move
<utility>
라이브러리인자로 들어온 값을
R-value
로 리턴해준다.
예제
std::move
를 사용하지 않은 예제main.cpp
#include <iostream> #include "Resource.h" #include "AutoPtr.h" using namespace std; int main() { AutoPtr<Resource> res1(new Resource(10000000)); cout << res1.ptr_ << endl; AutoPtr<Resource> res2 = res1; cout << res1.ptr_ << endl; cout << res2.ptr_ << endl; } /* stdout stderr Resource length constructed AutoPtr default constructor 0158E360 AutoPtr copy constructor Resource default constructed Resource copy assignment 0158E360 0158E408 AutoPtr destructor Resource destoryed AutoPtr destructor Resource destoryed */
Resource.h
#pragma once #include <iostream> class Resource { public: int *data_ = nullptr; unsigned length_ = 0; Resource() { std::cout << "Resource default constructed\n"; } Resource(unsigned length) { std::cout << "Resource length constructed\n"; init(length); } Resource(const Resource& res) { std::cout << "Resource copy constructed\n"; init(res.length_); for (unsigned i = 0; i < length_; ++i) data_[i] = res.data_[i]; } ~Resource() { std::cout << "Resource destoryed\n"; if (data_ != nullptr) delete[] data_; } void init(unsigned length) { data_ = new int[length]; length_ = length; } Resource& operator = (Resource& res) { std::cout << "Resource copy assignment\n"; if (&res == this) return *this; if (data_ != nullptr) delete[] data_; init(res.length_); for (unsigned i = 0; i < length_; ++i) data_[i] = res.data_[i]; return *this; } void print() { for (unsigned i = 0; i < length_; ++i) std::cout << data_[i] << ' '; std::cout << std::endl; } };
AutoPtr.h
#pragma once #include <iostream> template<class T> class AutoPtr { public: T* ptr_; AutoPtr(T *ptr = nullptr) : ptr_(ptr) { std::cout << "AutoPtr default constructor\n"; } AutoPtr(const AutoPtr& a) : ptr_(a.ptr_) { std::cout << "AutoPtr copy constructor\n"; ptr_ = new T; *ptr_ = *a.ptr_; } AutoPtr(AutoPtr&& a) : ptr_(a.ptr_) { std::cout << "AutoPtr move constructor\n"; a.ptr_ = nullptr; } ~AutoPtr() { std::cout << "AutoPtr destructor\n"; if (ptr_ != nullptr) delete ptr_; } AutoPtr& operator = (const AutoPtr& a) { std::cout << "AutoPtr copy assignment\n"; if (&a == this) return *this; if (ptr_ != nullptr) delete ptr_; ptr_ = new T; *ptr_ = *a.ptr_; return *this; } AutoPtr& operator = (AutoPtr&& a) { std::cout << "AutoPtr move assignment\n"; if (&a == this) return *this; if (ptr_ != nullptr) delete ptr_; ptr_ = a.ptr_; a.ptr_ = nullptr; return *this; } };
위의 코드에서
main.cpp
에<utility>
라이브러리를include
하고,std::move
를 사용하면 다음과 같다.main.cpp
#include <iostream> #include <utility> #include "Resource.h" #include "AutoPtr.h" using namespace std; int main() { AutoPtr<Resource> res1(new Resource(10000000)); cout << res1.ptr_ << endl; AutoPtr<Resource> res2 = std::move(res1); cout << res1.ptr_ << endl; cout << res2.ptr_ << endl; } /* stdout stderr Resource length constructed AutoPtr default constructor 00CADF50 AutoPtr move constructor 00000000 00CADF50 AutoPtr destructor Resource destoryed AutoPtr destructor */
Swap
예제
main.cpp
#include <iostream>
#include <utility>
#include "Resource.h"
#include "AutoPtr.h"
using namespace std;
template<typename T>
void MySwap(T& a, T& b)
{
T tmp{ std::move(a) };
a = std::move(b);
b = std::move(tmp);
}
int main()
{
AutoPtr<Resource> res1(new Resource(3));
res1->setAll(3);
AutoPtr<Resource> res2(new Resource(5));
res2->setAll(5);
res1->print();
res2->print();
MySwap(res1, res2);
res1->print();
res2->print();
}
/* stdout stderr
Resource length constructed
AutoPtr default constructor
Resource length constructed
AutoPtr default constructor
3 3 3
5 5 5 5 5
AutoPtr move constructor
AutoPtr move assignment
AutoPtr move assignment
AutoPtr destructor
5 5 5 5 5
3 3 3
AutoPtr destructor
Resource destoryed
AutoPtr destructor
Resource destoryed
*/
Resource.h
#pragma once
#include <iostream>
class Resource
{
public:
int *data_ = nullptr;
unsigned length_ = 0;
Resource()
{
std::cout << "Resource default constructed\n";
}
Resource(unsigned length)
{
std::cout << "Resource length constructed\n";
init(length);
}
Resource(const Resource& res)
{
std::cout << "Resource copy constructed\n";
init(res.length_);
for (unsigned i = 0; i < length_; ++i)
data_[i] = res.data_[i];
}
~Resource()
{
std::cout << "Resource destoryed\n";
if (data_ != nullptr) delete[] data_;
}
void init(unsigned length)
{
data_ = new int[length];
length_ = length;
}
Resource& operator = (Resource& res)
{
std::cout << "Resource copy assignment\n";
if (&res == this) return *this;
if (data_ != nullptr) delete[] data_;
init(res.length_);
for (unsigned i = 0; i < length_; ++i)
data_[i] = res.data_[i];
return *this;
}
void print()
{
for (unsigned i = 0; i < length_; ++i)
std::cout << data_[i] << ' ';
std::cout << std::endl;
}
void setAll(const int& v)
{
for (unsigned i = 0; i < length_; ++i)
data_[i] = v;
}
};
AutoPtr.h
#pragma once
#include <iostream>
template<class T>
class AutoPtr
{
public:
T* ptr_;
AutoPtr(T *ptr = nullptr)
: ptr_(ptr)
{
std::cout << "AutoPtr default constructor\n";
}
AutoPtr(const AutoPtr& a)
: ptr_(a.ptr_)
{
std::cout << "AutoPtr copy constructor\n";
ptr_ = new T;
*ptr_ = *a.ptr_;
}
AutoPtr(AutoPtr&& a)
: ptr_(a.ptr_)
{
std::cout << "AutoPtr move constructor\n";
a.ptr_ = nullptr;
}
~AutoPtr()
{
std::cout << "AutoPtr destructor\n";
if (ptr_ != nullptr) delete ptr_;
}
AutoPtr& operator = (const AutoPtr& a)
{
std::cout << "AutoPtr copy assignment\n";
if (&a == this)
return *this;
if (ptr_ != nullptr) delete ptr_;
ptr_ = new T;
*ptr_ = *a.ptr_;
return *this;
}
AutoPtr& operator = (AutoPtr&& a)
{
std::cout << "AutoPtr move assignment\n";
if (&a == this)
return *this;
if (ptr_ != nullptr) delete ptr_;
ptr_ = a.ptr_;
a.ptr_ = nullptr;
return *this;
}
T* operator->() const { return ptr_; }
};
대부분의 라이브러리는 R-value
에 대해서도 정의가 되어있다.
#include <iostream>
#include <utility>
#include <vector>
using namespace std;
int main()
{
vector<string> v;
string str = "Hello";
v.push_back(str);
cout << str << endl;
cout << v[0] << endl;
v.push_back(std::move(str));
cout << str << endl;
cout << v[0] << ' ' << v[1] << endl;
}
/* stdout stderr
Hello
Hello
Hello Hello
*/
'C++ > Library' 카테고리의 다른 글
C++ shared_ptr (0) | 2021.03.24 |
---|---|
C++ unique_ptr (0) | 2021.03.24 |
C++ 출력 스트림 끊기 (0) | 2021.03.24 |
C++ std::exception (0) | 2021.03.22 |
C++ reference_wrapper (0) | 2021.03.21 |