- ๋ฌด์์ ๋๊น?
- ๋ฌด์์ํฉ๋๊น?
- ์ธ์ ์ฌ์ฉํด์ผํฉ๋๊น?
์ข์ ๋งํฌ๋ฅผ ๋ถํ๋๋ฆฝ๋๋ค.
๋ต๋ณ
C ++ 11 R- ๊ฐ ์ฐธ์กฐ ๋ฐ ์ด๋ ์์ฑ์์ ๋ํ Wikipedia ํ์ด์ง
- C ++ 11์์๋ ๋ณต์ฌ ์์ฑ์ ์ธ์๋ ๊ฐ์ฒด์ ์ด๋ ์์ฑ์๊ฐ์์ ์ ์์ต๋๋ค.
๋ํ ๋ณต์ฌ ํ ๋น ์ฐ์ฐ์ ์ธ์๋ ์ด๋ ํ ๋น ์ฐ์ฐ์๊ฐ ์์ต๋๋ค. - ๊ฐ์ฒด์ ์ ํ์ด โrvalue-referenceโ(
Type &&
) ์ธ ๊ฒฝ์ฐ ์ด๋ ์์ฑ์ ๋์ ์ด๋ ์์ฑ์๊ฐ ์ฌ์ฉ๋ฉ๋๋ค . std::move()
๊ฐ์ฒด์ ๋ํ rvalue-reference๋ฅผ ์์ฑํ์ฌ ๊ฐ์ฒด์์ ์ด๋ํ ์ ์๋๋กํ๋ ์บ์คํธ์ ๋๋ค.
๋ณต์ฌ๋ณธ์ ํผํ๋ ์๋ก์ด C ++ ๋ฐฉ๋ฒ์
๋๋ค. ์๋ฅผ ๋ค์ด ์ด๋ ์์ฑ์๋ฅผ ์ฌ์ฉํ๋ฉด a std::vector
๋ ๋ฐ์ดํฐ์ ๋ํ ๋ด๋ถ ํฌ์ธํฐ๋ฅผ ์ ๊ฐ์ฒด์ ๋ณต์ฌํ์ฌ ์ด๋ ๋ ๊ฐ์ฒด๋ฅผ ์ด๋ ๋ ์ํ๋ก ์ ์งํ๋ฏ๋ก ๋ชจ๋ ๋ฐ์ดํฐ๋ฅผ ๋ณต์ฌํ์ง๋ ์์ต๋๋ค. ์ด๊ฒ์ C ++-์ ํจํฉ๋๋ค.
์ด๋ ์๋ฏธ, rvalue, ์๋ฒฝํ ์ ๋ฌ์ ์ํด ์ธํฐ๋ท ๊ฒ์์ ์๋ํ์ญ์์ค.
๋ต๋ณ
1. โ๋ฌด์์ ๋๊น?โ
std::move()
๊ธฐ์ ์ ์ผ๋ก๋ ํจ์ ์ด์ง๋ง ์ค์ ๋ก ๋ ํจ์ ๊ฐ ์๋๋ผ๊ณ ๋งํ ์ ์์ต๋๋ค . ์ปดํ์ผ๋ฌ๊ฐ ํํ์์ ๊ฐ์ ๊ณ ๋ คํ๋ ๋ฐฉ์ ์ฌ์ด ์ ๋ณํ๊ธฐ ์
๋๋ค.
2. โ๋ฌด์์ํฉ๋๊น?โ
๊ฐ์ฅ ๋จผ์ ์ฃผ๋ชฉํ ๊ฒ์ std::move()
์ค์ ๋ก ์๋ฌด๊ฒ๋ ์์ง์ด์ง ์๋๋ค๋ ๊ฒ ์
๋๋ค. ํํ์์ ์ด๋ฆ์ด ์ง์ ๋ ๋ณ์์ ๊ฐ์ lvalue ์์ xvalue๋ก ๋ณํ ํฉ๋๋ค. xvalue๋ ์ปดํ์ผ๋ฌ์๊ฒ ๋ค์์ ์๋ ค์ค๋๋ค.
๋น์ ์ ์ ๋ฅผ ์ฝํํ๊ณ , ๋ด๊ฐ ๊ฐ์ง๊ณ ์๋ ๊ฒ์ ์ฎ๊ธฐ๊ณ ๋ค๋ฅธ ๊ณณ์์ ์ฌ์ฉํ ์ ์์ต๋๋ค (์ด์จ๋ ๊ณง ํ๊ดด ๋ ๊ฒ์ด๊ธฐ ๋๋ฌธ์) โ.
์ฆ,๋ฅผ ์ฌ์ฉํ ๋ std::move(x)
์ปดํ์ผ๋ฌ๊ฐ ์์ธ์ข
์ ํ์ฉํฉ๋๋ค x
. ๋ฐ๋ผ์ x
๋ฉ๋ชจ๋ฆฌ์ ์์ฒด ๋ฒํผ๊ฐ ์๋ค๋ฉด std::move()
์ปดํ์ผ๋ฌ๊ฐ ๋ค๋ฅธ ๊ฐ์ฒด๋ฅผ ์์ ํ ์ ์์ต๋๋ค.
prvalue (์ : ์์๋ก ์ ๋ฌ๋๋) ์์ ์ด๋ํ ์๋ ์์ง๋ง ๊ฑฐ์ ์ ์ฉํ์ง ์์ต๋๋ค.
3. โ์ธ์ ์ฌ์ฉํด์ผํฉ๋๊น?โ
์ด ์ง๋ฌธ์ํ๋ ๋ ๋ค๋ฅธ ๋ฐฉ๋ฒ์ โ๊ธฐ์กด ๊ฐ์ฒด์ ์์์ ์ด๋ป๊ฒ ์ ์ ํ ์ ์์ต๋๊น?โ์ ๋๋ค. ๊ธ์, ์์ฉ ํ๋ก๊ทธ๋จ ์ฝ๋๋ฅผ ์์ฑํ๋ค๋ฉด ์ปดํ์ผ๋ฌ๊ฐ ๋ง๋ ์์ ๊ฐ์ฒด๋ฅผ ๋ง์ด ์ฌ์ฉํ์ง ์์ ๊ฒ์ ๋๋ค. ๋ฐ๋ผ์ ์ฃผ๋ก ์์ฑ์, ์ฐ์ฐ์ ๋ฉ์๋, ํ์ค ๋ผ์ด๋ธ๋ฌ๋ฆฌ ์๊ณ ๋ฆฌ์ฆ๊ณผ ๊ฐ์ ํจ์ ๋ฑ์์ ๊ฐ์ฒด๋ฅผ ์๋์ผ๋ก ๋ง์ด ์์ฑํ๊ณ ํ๊ดดํ๋ ์ฅ์ ์์์ด ์์ ์ ์ํํฉ๋๋ค. ๋ฌผ๋ก , ๊ทธ๊ฒ์ ๋จ์ง ๊ฒฝํ์ ๋ฒ์น์ ๋๋ค.
์ผ๋ฐ์ ์ผ๋ก ๋ณต์ฌ ๋์ ํ ๊ฐ์ฒด์์ ๋ค๋ฅธ ๊ฐ์ฒด๋ก ๋ฆฌ์์ค๋ฅผ โ์ด๋โํฉ๋๋ค. @Guillaume ์์ด ํ์ด์ง์ ๋งํฌ๋์ด ์์ผ๋ฉฐ ๊ฐ๋จํ ์์ ๊ฐ ์์ต๋๋ค. ๋ ๊ฐ์ ๊ฐ์ฒด๋ฅผ ์ ์ ๋ณต์ฌ๋ก ๋ฐ๊พธ๋ ๊ฒ์ ๋๋ค.
template <class T>
swap(T& a, T& b) {
T tmp(a); // we now have two copies of a
a = b; // we now have two copies of b (+ discarded a copy of a)
b = tmp; // we now have two copies of tmp (+ discarded a copy of b)
}
์ด๋์ ์ฌ์ฉํ๋ฉด ์์์ ๋ณต์ฌํ์ง ์๊ณ ๊ตํ ํ ์ ์์ต๋๋ค.
template <class T>
swap(T& a, T& b) {
T tmp(std::move(a));
a = std::move(b);
b = std::move(tmp);
}
T
์ vector<int>
๋ฅผ ๋ค์ด ํฌ๊ธฐ๊ฐ n ์ผ ๋ ์ด๋ค ์ผ์ด ๋ฐ์ํ๋์ง ์๊ฐํด๋ณด์ญ์์ค . ์ฒซ ๋ฒ์งธ ๋ฒ์ ์์๋ 3 * n ์์๋ฅผ ์ฝ๊ณ ์๋๋ค. ๋ ๋ฒ์งธ ๋ฒ์ ์์๋ ๊ธฐ๋ณธ์ ์ผ๋ก ๋ฒกํฐ ๋ฒํผ์ ๋ํ 3 ๊ฐ์ ํฌ์ธํฐ์ 3 ๊ฐ์ ๋ฒํผ ํฌ๊ธฐ ๋ง ์ฝ๊ณ ์๋๋ค. ๋ฌผ๋ก , ์์
T
์ ์ด๋ป๊ฒ ์์ง์ด๋์ง๋ฅผ ์์์ผํฉ๋๋ค. ์ด ํด๋์ค๊ฐ T
์๋ํ๋ ค๋ฉด ํด๋์ค ์ ์ด๋ ํ ๋น ์ฐ์ฐ์์ ํด๋์ค ๋ฅผ ์ํ ์ด๋ ์์ฑ์๊ฐ ์์ด์ผํฉ๋๋ค.
๋ต๋ณ
๋ณต์ฌํ์ง ์๊ณ ๊ฐ์ฒด์ ๋ด์ฉ์ ๋ค๋ฅธ ๊ณณ์ผ๋ก โ์ ์กโํด์ผ ํ ๋ ์ด๋์ ์ฌ์ฉํ ์ ์์ต๋๋ค (์ฆ, ๋ด์ฉ์ด ๋ณต์ ๋์ง ์๊ธฐ ๋๋ฌธ์ unique_ptr๊ณผ ๊ฐ์ด ๋ณต์ฌ ํ ์์๋ ์ผ๋ถ ๊ฐ์ฒด์์ ์ฌ์ฉํ ์ ์์ต๋๋ค). std :: move๋ฅผ ์ฌ์ฉํ์ฌ ๊ฐ์ฒด๊ฐ ๋ณต์ฌํ์ง ์๊ณ ์์ ๊ฐ์ฒด์ ๋ด์ฉ์ ๊ฐ์ ธ์ ๋ง์ ์๊ฐ์ ์ ์ฝ ํ ์๋ ์์ต๋๋ค.
์ด ๋งํฌ๋ ์ ๋ง ๋์์ด๋์์ต๋๋ค.
http://thbecker.net/articles/rvalue_references/section_01.html
๋ต๋ณ์ด ๋๋ฌด ๋ฆ์ด์ง๋ฉด ์ฃ์กํ์ง๋ง std :: move์ ๋ํ ์ข์ ๋งํฌ๋ฅผ ์ฐพ๊ณ ์์์ผ๋ฉฐ ์์ ๋งํฌ๊ฐ โaustereโ๋ณด๋ค ์ฝ๊ฐ ์ปธ์ต๋๋ค.
์ด๊ฒ์ r- ๊ฐ ์ฐธ์กฐ์ ์ค์ ์๋๊ณ ์์ผ๋ฉฐ, ์ฌ๊ธฐ์๋ ์ปจํ ์คํธ๋ฅผ ์ฌ์ฉํด์ผํ๋ฉฐ ๋ ์์ธํ๋ค๊ณ ์๊ฐํฉ๋๋ค.์ด ๋งํฌ๋ฅผ ์ฌ๊ธฐ์ ๊ณต์ ํ๊ณ ์ถ์์ต๋๋ค.
๋ต๋ณ
Q : ๋ฌด์์
๋๊น std::move
?
A : std::move()
rvalue ์ฐธ์กฐ๋ก ์บ์คํธํ๊ธฐ์ํ C ++ ํ์ค ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ ํจ์์
๋๋ค.
๊ฐ๋จ std::move(t)
ํ๊ฒ ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
static_cast<T&&>(t);
rvalue๋ ๋ณ์์ ์ ์ฅ๋์ง ์๋ ์ค๊ฐ ํจ์ ๊ฒฐ๊ณผ์ ๊ฐ์ด์ด๋ฅผ ์ ์ํ๋ ํํ์์ ๋์ด ์ง์๋์ง ์๋ ์์ ๊ฐ์ ๋๋ค.
int a = 3; // 3 is a rvalue, does not exist after expression is evaluated
int b = a; // a is a lvalue, keeps existing after expression is evaluated
std :: move ()์ ๊ตฌํ์ ๋ค์๊ณผ ๊ฐ์ด N2027 : โRvalue ์ฐธ์กฐ์ ๋ํ ๊ฐ๋ตํ ์๊ฐโ ์ ์ ๊ณต๋ฉ๋๋ค.
template <class T>
typename remove_reference<T>::type&&
std::move(T&& a)
{
return a;
}
๋ณด์๋ค์ํผ , ๊ฐ ( ), ์ฐธ์กฐ ์ ํ ( ) ๋๋ rvalue ์ฐธ์กฐ ( )๋ฅผ ์ฌ์ฉํ์ฌ ํธ์ถํ๋๋ผ๋ ์๊ด์์ด std::move
๋ฐํํฉ๋๋ค .T&&
T
T&
T&&
Q : ๋ฌด์์ํฉ๋๊น?
A : ์บ์คํธ๋ก์ ๋ฐํ์ ์ค์ ์๋ฌด๊ฒ๋ํ์ง ์์ต๋๋ค. ์ปดํ์ผ๋ฌ์๊ฒ ์ฐธ์กฐ๋ฅผ rvalue๋ก ๊ณ์ ๊ณ ๋ คํ๊ณ ์๋ค๊ณ ์๋ฆฌ๋ ๊ฒ์ ์ปดํ์ผ ํ์์๋ง ๊ด๋ จ์ด ์์ต๋๋ค.
foo(3 * 5); // obviously, you are calling foo with a temporary (rvalue)
int a = 3 * 5;
foo(a); // how to tell the compiler to treat `a` as an rvalue?
foo(std::move(a)); // will call `foo(int&& a)` rather than `foo(int a)` or `foo(int& a)`
ํ์ง ์๋ ๊ฒ :
- ๋ ผ์์ ์ฌ๋ณธ์ ๋ง๋์ญ์์ค
- ๋ณต์ฌ ์์ฑ์ ํธ์ถ
- ์ธ์ ๊ฐ์ฒด ๋ณ๊ฒฝ
Q : ์ธ์ ์ฌ์ฉํด์ผํฉ๋๊น?
A : std::move
rvalue (์์ ํํ์)๊ฐ ์๋ ์ธ์๋ก ์ด๋ ์๋ฏธ๋ฅผ ์ง์ํ๋ ํจ์๋ฅผ ํธ์ถํ๋ ค๋ ๊ฒฝ์ฐ ์ฌ์ฉํด์ผ ํฉ๋๋ค.
์ด๊ฒ์ ๋ค์๊ณผ ๊ฐ์ ํ์ ์ง๋ฌธ์ ์ ๊ธฐํฉ๋๋ค.
-
์ด๋ ์๋ฏธ ๋ ๋ฌด์์ ๋๊น? ๋ณต์ฌ ์๋งจํฑ๊ณผ ๋์กฐ์ ์ผ๋ก ์๋งจํฑ ์ด๋์ ์ค๋ธ์ ํธ์ ๋ฉค๋ฒ๊ฐ ๋ค๋ฅธ ์ค๋ธ์ ํธ์ ๋ฉค๋ฒ๋ฅผ ๋ณต์ฌํ๋ ๋์ โ์ทจ๋โํ์ฌ ์ด๊ธฐํ๋๋ ํ๋ก๊ทธ๋๋ฐ ๊ธฐ์ ์ ๋๋ค. ์ด๋ฌํ โ์ธ๊ณโ๋ ํฌ์ธํฐ ๋ฐ ๋ฆฌ์์ค ํธ๋ค์์๋ง ์๋ฏธ๊ฐ ์์ผ๋ฉฐ, ๊ธฐ๋ณธ ๋ฐ์ดํฐ๊ฐ ์๋ ํฌ์ธํฐ ๋๋ ์ ์ ํธ๋ค์ ๋ณต์ฌํ์ฌ ์ ๋ ดํ๊ฒ ์ ์กํ ์ ์์ต๋๋ค.
-
์ด๋ ์๋งจํฑ์ ์ง์ํ๋ ํด๋์ค์ ๊ฐ์ฒด๋ ๋ฌด์์ ๋๊น? ๋ฉค๋ฒ๋ฅผ ๋ณต์ฌํ๋ ๋์ ๋ฉค๋ฒ๋ฅผ ์ ์กํ๋ ๊ฒ์ด ๋์์ด๋๋ ๊ฒฝ์ฐ ์์ ์ ํด๋์ค์์ ์ด๋ ์๋ฏธ๋ก ์ ๊ตฌํํ๋ ๊ฒ์ ๊ฐ๋ฐ์์ ์ฑ ์์ ๋๋ค. ์ด๋ ์๋ฏธ๋ก ์ ๊ตฌํํ๋ฉด ์ด๋ ์๋ฏธ๋ก ์ ์ฌ์ฉํ์ฌ ํด๋์ค๋ฅผ ํจ์จ์ ์ผ๋ก ์ฒ๋ฆฌํ๋ ๋ฐ ๋ํ ์ง์์ ์ถ๊ฐ ํ ๋ง์ ๋ผ์ด๋ธ๋ฌ๋ฆฌ ํ๋ก๊ทธ๋๋จธ์ ์์ ์ผ๋ก๋ถํฐ ์ง์ ํํ์ ์ป์ ์ ์์ต๋๋ค.
-
์ ์ปดํ์ผ๋ฌ๊ฐ ์ค์ค๋ก ์์๋ผ ์ ์์ต๋๊น? ๋ฌ๋ฆฌ ๋งํ์ง ์๋ ํ ์ปดํ์ผ๋ฌ๋ ํจ์์ ๋ค๋ฅธ ์ค๋ฒ๋ก๋๋ฅผ ํธ์ถ ํ ์ ์์ต๋๋ค. ์ปดํ์ผ๋ฌ๊ฐ ์ ๊ท ๋๋ ์ด๋ ๋ฒ์ ์ ํจ์๋ฅผ ํธ์ถํด์ผํ๋์ง ์ ํํ๋๋ก ๋์์ผํฉ๋๋ค.
-
์ด๋ค ์ํฉ์์ ์ปดํ์ผ๋ฌ์๊ฒ ๋ณ์๋ฅผ rvalue๋ก ์ทจ๊ธํด์ผํ๋ค๊ณ ๋งํ๊ณ ์ถ์ต๋๊น? ์ด๋ ์ค๊ฐ ๊ฒฐ๊ณผ๊ฐ ๋ณต๊ตฌ ๋ ์ ์์์ ์๊ณ ์๋ ํ ํ๋ฆฌํธ ๋๋ ๋ผ์ด๋ธ๋ฌ๋ฆฌ ํจ์์์ ๋ฐ์ํฉ๋๋ค.
๋ต๋ณ
std :: move ์์ฒด๋ ์ค์ ๋ก ๋ง์ ์์ ์ ์ํํ์ง ์์ต๋๋ค. ๊ฐ์ฒด์ ์ด๋ ์์ฑ์๋ฅผ ํธ์ถํ๋ค๊ณ ์๊ฐํ์ง๋ง ์ค์ ๋ก ์ ํ ๋ณํ์ ์ํํฉ๋๋ค (lvalue ๋ณ์๋ฅผ rvalue๋ก ์บ์คํ ํ์ฌ ํด๋น ๋ณ์๋ฅผ ์ด๋ ์์ฑ์ ๋๋ ํ ๋น ์ฐ์ฐ์์ ์ธ์๋ก ์ ๋ฌํ ์ ์์).
๋ฐ๋ผ์ std :: move๋ ์ด๋ ์๋ฏธ๋ก ์ ์ฌ์ฉํ๋ ์ ๊ตฌ์๋ก ์ฌ์ฉ๋ฉ๋๋ค. ์ด๋ ์๋ฏธ๋ก ์ ๊ธฐ๋ณธ์ ์ผ๋ก ์์ ๊ฐ์ฒด๋ฅผ ์ฒ๋ฆฌํ๋ ํจ์จ์ ์ธ ๋ฐฉ๋ฒ์ ๋๋ค.
๊ฐ์ฒด ๊ณ ๋ ค A = B + C + D + E + F;
์ด๊ฒ์ ๋ฉ์ง ์ฝ๋์ด์ง๋ง E + F๋ ์์ ๊ฐ์ฒด๋ฅผ ์์ฑํฉ๋๋ค. ๊ทธ๋ฐ ๋ค์ D + temp๋ ๋ค๋ฅธ ์์ ๊ฐ์ฒด ๋ฑ์ ์์ฑํฉ๋๋ค. ํด๋์ค์ ๊ฐ ์ผ๋ฐ โ+โ์ฐ์ฐ์์์ ๋ฅ ์นดํผ๊ฐ ๋ฐ์ํฉ๋๋ค.
์๋ฅผ ๋ค์ด
Object Object::operator+ (const Object& rhs) {
Object temp (*this);
// logic for adding
return temp;
}
์ด ํจ์์์ ์์ ๊ฐ์ฒด๋ฅผ ์์ฑํ๋ ๊ฒ์ ์ธ๋ชจ๊ฐ ์์ต๋๋ค. ์ด๋ฌํ ์์ ๊ฐ์ฒด๋ ๋ฒ์๋ฅผ ๋ฒ์ด๋๋ฉด ์ค ๋์์ ์ญ์ ๋ฉ๋๋ค.
์คํ๋ ค ์ด๋ ์๋ฏธ๋ก ์ ์ฌ์ฉํ์ฌ ์์ ๊ฐ์ฒด๋ฅผ โ์ฝํโํ๊ณ
Object& Object::operator+ (Object&& rhs) {
// logic to modify rhs directly
return rhs;
}
๋ถํ์ํ๊ฒ ๊น์ ์ฌ๋ณธ์ด ๋ง๋ค์ด์ง์ง ์๋๋กํฉ๋๋ค. ์๋ฅผ ์ฐธ์กฐํ๋ฉด ๋ฅ ์นดํผ๊ฐ ๋ฐ์ํ๋ ์ ์ผํ ๋ถ๋ถ์ ์ด์ E + F์ ๋๋ค. ๋๋จธ์ง๋ ์ด๋ ์๋ฏธ๋ก ์ ์ฌ์ฉํฉ๋๋ค. ๊ฒฐ๊ณผ๋ฅผ A์ ํ ๋นํ๋ ค๋ฉด ์ด๋ ์์ฑ์ ๋๋ ํ ๋น ์ฐ์ฐ์๋ ๊ตฌํํด์ผํฉ๋๋ค.
๋ต๋ณ
โ๋ฌด์์ ๋๊น?โ ๊ทธ๋ฆฌ๊ณ โ๊ทธ๊ฒ์ ๋ฌด์์ํฉ๋๊น?โ ์์์ ์ค๋ช ํ์ต๋๋ค.
โ์ฌ์ฉํด์ผ ํ ๋โ์ ๋ํ ์๋ฅผ ๋ค๊ฒ ์ต๋๋ค.
์๋ฅผ ๋ค์ด, ํฐ ๋ฐฐ์ด๊ณผ ๊ฐ์ ๋ง์ ๋ฆฌ์์ค๊ฐ์๋ ํด๋์ค๊ฐ ์์ต๋๋ค.
class ResHeavy{ // ResHeavy means heavy resource
public:
ResHeavy(int len=10):_upInt(new int[len]),_len(len){
cout<<"default ctor"<<endl;
}
ResHeavy(const ResHeavy& rhs):_upInt(new int[rhs._len]),_len(rhs._len){
cout<<"copy ctor"<<endl;
}
ResHeavy& operator=(const ResHeavy& rhs){
_upInt.reset(new int[rhs._len]);
_len = rhs._len;
cout<<"operator= ctor"<<endl;
}
ResHeavy(ResHeavy&& rhs){
_upInt = std::move(rhs._upInt);
_len = rhs._len;
rhs._len = 0;
cout<<"move ctor"<<endl;
}
// check array valid
bool is_up_valid(){
return _upInt != nullptr;
}
private:
std::unique_ptr<int[]> _upInt; // heavy array resource
int _len; // length of int array
};
ํ ์คํธ ์ฝ๋ :
void test_std_move2(){
ResHeavy rh; // only one int[]
// operator rh
// after some operator of rh, it becomes no-use
// transform it to other object
ResHeavy rh2 = std::move(rh); // rh becomes invalid
// show rh, rh2 it valid
if(rh.is_up_valid())
cout<<"rh valid"<<endl;
else
cout<<"rh invalid"<<endl;
if(rh2.is_up_valid())
cout<<"rh2 valid"<<endl;
else
cout<<"rh2 invalid"<<endl;
// new ResHeavy object, created by copy ctor
ResHeavy rh3(rh2); // two copy of int[]
if(rh3.is_up_valid())
cout<<"rh3 valid"<<endl;
else
cout<<"rh3 invalid"<<endl;
}
์๋์ ๊ฐ์ด ์ถ๋ ฅ :
default ctor
move ctor
rh invalid
rh2 valid
copy ctor
rh3 valid
์ฐ๋ฆฌ๋ ๊ฒ์ ์ ์ ์์ต๋๋ค std::move
์ผ๋ก move constructor
๋ง๋ ๋ค ์ฝ๊ฒ ์์์ ๋ณํ.
๋ค๋ฅธ std::move
์ ์ฉํ ๊ณณ์ด ์์ต๋๊น?
std::move
์์ ๋ฐฐ์ด์ ์ ๋ ฌ ํ ๋๋ ์ ์ฉ ํ ์ ์์ต๋๋ค. ์ ํ ์ ๋ ฌ ๋ฐ ๋ฒ๋ธ ์ ๋ ฌ๊ณผ ๊ฐ์ ๋ง์ ์ ๋ ฌ ์๊ณ ๋ฆฌ์ฆ์ ์์ ์์ ๊ต์ฒดํ์ฌ ์๋ํฉ๋๋ค. ์ด์ ์๋ ์ค์ํ์ ์ํํ๊ธฐ ์ํด ์นดํผ ์๋งจํฑ์ ์์งํด์ผํ์ต๋๋ค. ์ด์ ๋ณด๋ค ํจ์จ์ ์ธ ์ด๋ ์๋ฏธ๋ก ์ ์ฌ์ฉํ ์ ์์ต๋๋ค.
ํ๋์ ์ค๋งํธ ํฌ์ธํฐ๋ก ๊ด๋ฆฌ๋๋ ์ปจํ ์ธ ๋ฅผ ๋ค๋ฅธ ์ค๋งํธ ํฌ์ธํฐ๋ก ์ฎ๊ธฐ๋ ค๋ ๊ฒฝ์ฐ์๋ ์ ์ฉ ํ ์ ์์ต๋๋ค.
์ธ์ฉ :
๋ต๋ณ
๋ค์์ (๊ฐ๋จํ) ์ฌ์ฉ์ ์ ์ ๋ฒกํฐ์ std :: move๋ฅผ ์ฌ์ฉํ๋ ์ ์ฒด ์์ ๋๋ค.
์์ ์ถ๋ ฅ :
c: [10][11]
copy ctor called
copy of c: [10][11]
move ctor called
moved c: [10][11]
๋ค์๊ณผ ๊ฐ์ด ์ปดํ์ผํ์ญ์์ค.
g++ -std=c++2a -O2 -Wall -pedantic foo.cpp
์ํธ:
#include <iostream>
#include <algorithm>
template<class T> class MyVector {
private:
T *data;
size_t maxlen;
size_t currlen;
public:
MyVector<T> () : data (nullptr), maxlen(0), currlen(0) { }
MyVector<T> (int maxlen) : data (new T [maxlen]), maxlen(maxlen), currlen(0) { }
MyVector<T> (const MyVector& o) {
std::cout << "copy ctor called" << std::endl;
data = new T [o.maxlen];
maxlen = o.maxlen;
currlen = o.currlen;
std::copy(o.data, o.data + o.maxlen, data);
}
MyVector<T> (const MyVector<T>&& o) {
std::cout << "move ctor called" << std::endl;
data = o.data;
maxlen = o.maxlen;
currlen = o.currlen;
}
void push_back (const T& i) {
if (currlen >= maxlen) {
maxlen *= 2;
auto newdata = new T [maxlen];
std::copy(data, data + currlen, newdata);
if (data) {
delete[] data;
}
data = newdata;
}
data[currlen++] = i;
}
friend std::ostream& operator<<(std::ostream &os, const MyVector<T>& o) {
auto s = o.data;
auto e = o.data + o.currlen;;
while (s < e) {
os << "[" << *s << "]";
s++;
}
return os;
}
};
int main() {
auto c = new MyVector<int>(1);
c->push_back(10);
c->push_back(11);
std::cout << "c: " << *c << std::endl;
auto d = *c;
std::cout << "copy of c: " << d << std::endl;
auto e = std::move(*c);
delete c;
std::cout << "moved c: " << e << std::endl;
}