[C++] R-Value Reference์ Move Semantic
R-Value Reference(์ดํ ์ค๋ฅธ๊ฐ ์ฐธ์กฐ)๋ C++11๋ถํฐ ์ถ๊ฐ๋ ์์ฃผ ๋ณต์กํ๋ฉด์๋ ๋ฉ์ง ๋ ์์ด๋ค.
์ด๊ฒ ๋์ฒด ๋ญํ๋ ๋์ธ๊ณ ํ๋ฉด, ์์ฃผ ์๋ก ์ ์ธ ๋ถ๋ถ๊น์ง ์ ํด๋ค์ด๊ฐ ํ์๊ฐ ์๋ค.
์๋ ์ฝ๋๋ฅผ ๋ด๋ณด์.
int num;
num = 33;
L: ์ฌ๊ธฐ์ num์ ์ผ์ชฝ์ ์๋ค. ๊ทธ๋ฆฌ๊ณ ์ด๋ฆ์ด ์๋ค. ๊ทธ๋ฆฌ๊ณ ํํ์์ด ์ข
๋ฃ๋์ด๋ ์กด์ฌํ๋ค. ๋ํ ๋ฉ๋ชจ๋ฆฌ ์
์ด๋ฏ๋ก ์ฃผ์์ฐ์ฐ(&)์ ์ฌ์ฉํ ์ ์๋ค. ์ด๊ฒ์ด ์ผ๊ฐ์ด๋ค.
R: ์ค๋ฅธ์ชฝ์๋ 33์ด ์๋ค. ์ด๊ฑด ์ด๋ฆ์ด ์๋ค. ๊ทธ๋ฅ ๊ฐ์ด num์ผ๋ก ์ ๋ฌ๋ ๋ฟ์ด๊ณ , ํํ์์ด ๋๋๋ฉด ์ฆ๋ฐํ๋ค. ๋ํ ์์์ด๋ฏ๋ก ์ฃผ์์ฐ์ฐ์ ์ฌ์ฉํ ์ ์๋ค. ์ด๊ฒ์ด ์ค๋ฅธ๊ฐ์ด๋ค.
const string& s... ๊ฐ์,
์ด์ ๊น์ง ์ฐ๋ฆฌ๊ฐ ์ฌ์ฉํ๋ ์ฐธ์กฐ๋ ์ผ๊ฐ์ฐธ์กฐ์๋ค.
๊ธฐ์กด์ ์กด์ฌํ๋ ๋ณ์(์ผ๊ฐ)๋ฅผ ์ฐธ์กฐํ์ผ๋๊น.
ํ์ง๋ง ์ด์ ์ฐ๋ฆฌ๊ฐ ์ ๊ทผํด๋ณผ ์ค๋ฅธ๊ฐ ์ฐธ์กฐ๋ ์ ๋ฐ ์ด๋ฆ์๋ ์์ ๊ฐ๋ค๋ง์ ์ฐธ์กฐํ ์ ์๋ค.
ํ๊ธฐ๋ฒ์ ์๋์ ๊ฐ์ด, &๋์ ์ &&๋ฅผ ์ฌ์ฉํ๋ค.
int && ref = 333; //์ค๋ฅธ๊ฐ 333์ ์ฐธ์กฐ
์ผ๊ฐ๋ std::move๋ฅผ ์ฌ์ฉํ๋ฉด ์ค๋ฅธ๊ฐ ์ฐธ์กฐ์ ๋ฌถ์์ ์๋ค.
std::string s = "text";
std::string&& ref = std::move(s);
//์ด๋ฆ์ด move์ง๋ง ์ง์ง ์ด๋ํ๋๊ฑด ์๋๊ณ &&์ฐธ์กฐ๋ก ์บ์คํ
๋ง ํด์ค
์ค๋ฅธ๊ฐ ์ฐธ์กฐ์๋ ๊ธฐ์กด์ ์ผ๊ฐ ์ฐธ์กฐ์์ฒ๋ผ ๊ฐ์ ์ ๊ทผํด์ ์ด๋์ ๋ ์ธ์ ์๋ค.

๊ทผ๋ฐ ์ด๊ฒ ๋ค๋ผ๋ฉด ์ด๊ฑธ ๊ตฌ๋ถํด์ ์ธ ์ด์ ๊ฐ ์ ํ ์๋ค. ๊ทธ๋ฅ ์ผ๊ฐ์ฐธ์กฐ ์จ๋ ๋๊ฐ์ด ๋์์?
๊ทธ๋ ๋ค. ์ด ์ค๋ฅธ๊ฐ ์ฐธ์กฐ๋ก ๊ฐ์ด ๋ค๋ฅธ ๋ณ์์ ์ ๋ฌ๋๊ณ , ๊ทธ ๋ณ์์ ํ์
์ ํด๋นํ๋ ์ด๋ ์์ฑ์(ํน์ ๋์
์)๊ฐ ์๋ค๋ฉด, **๋ฌด๋ธ ์๋งจํฑ(Move Semantic)**์ด๋ผ๋ ๊ฒ์ด ๋ฐ์ํ๋ค.
๋ง ๊ทธ๋๋ก ์ด๋(move)์ ์ํํ๋ค.
์ปดํจํฐ์์ ๋ฌด๊ฑฐ์ด ์์ ํ์ผ๋ค์ ์ฎ๊ฒจ๋ณธ ์ ์ด ์์๊ฒ์ด๋ค.
ํ์ผ์ด ๋๋ฌด ๋ฌด๊ฒ๋ค๋ฉด ๊ทธ ํ์ผ์ ๋ณต์ฌํ๊ณ ๋ถ์ฌ๋ฃ๋(Ctrl+c,v) ์๋๋ ์์ฒญํ๊ฒ ๋๋ ค์ง๋ค.
ํ์ง๋ง ํ์ผ์ ์๋ผ๋ด๊ณ ๋ถ์ผ(Ctrl+x,v) ๋๋ ๋ณ๋ค๋ฅธ ์๊ฐ์ด ์์๋์ง ์๊ณ ๋๋ฑ ์๋ฃ๋๋ค. ์ด๊ฒ์ด ํ์ผ์ด ํ ๊ตฐ๋ฐ๋ง ์กด์ฌํ ๊ฒ์ ๋ณด์ฅํ๋ ๋ฐ์ ๋ฐ์ํ๋ ์ผ์ข
์ ์ด๋์ด๋ค.
์์ ์ธ๊ธํ ๋ฌด๋ธ์๋งจํฑ๋ ์ด์ ๊ฐ์ ์๋ฆฌ๋ผ ๋ณด๋ฉด ๋๋ค.
์์๋ฅผ ํ๋ฒ ๋ณด์.
//๊ฐ์ 1: s ์์ ๋ด๊ธด ๋ฌธ์์ด์ ํฌ๊ธฐ๊ฐ ํฌ๋ค.
std::string s = "...";
//์ด ์์ ์์ s๋ ๋์ด์ ํ์๊ฐ ์๋ค.
//s2์์ ์ฎ๊ฒจ์ s2๋ก๋ง ์ฐ๋ฉด ๋๋ค.
std::string s2 = s;
์ด๋ฌ๋ฉด s2์ ๋ณต์ฌ์์ฑ์๊ฐ ํธ์ถ๋๋ฉด์ s์ ๋ด๋ถ๊ฐ์ ์ผ์ผ์ด ๋ณต์ฌํด์ ๊ฐ์ ธ๊ฐ๋ค.
๊ธฐ์กด s์ ํฌ๊ธฐ๊ฐ ํด์๋ก ์์๋๋ ์๊ฐ๋ ์ ํ์ ์ผ๋ก ์ฆ๊ฐํ ๊ฒ์ด๋ค.
ํ์ง๋ง ์ด๋ ๊ฒ ํ๋ค๋ฉด
std::string s2 = std::move(s);
//s๋ฅผ std::string&&์ผ๋ก ์บ์คํ
//s2์ ์ด๋์์ฑ์ ํธ์ถ
s์ ๊ธธ์ด์ ์๊ด์์ด ์ด ์์
์ ์์ฃผ ์์ ์์์๊ฐ์ ์ข
๋ฃ๋๋ค.
๊ทธ๋ฆฌ๊ณ ๊ธฐ์กด์ s๋ ํ
๋น๊ฒ๋๋ค.
๊ทธ๋ฆฌ๊ณ ๋ฌด๋ธ์๋งจํฑ์ ์ฐ์ฐ์ค์ ๋ฐ์ํ ์์๊ฐ์ฒด๋ฅผ ๋ค๋ฃฐ๋๋ ํจ์ฉ์ ๋ณด์ธ๋ค.
std::string s = "hello";
std::string s2 = " world";
std::string s3 = s+s2;
์๋ ๋ฐฉ์๋๋ก ์๊ฐํด๋ณด์. ์ ์ฝ๋์ ์ธ๋ฒ์งธ์ค์์ s์ s2๊ฐ ๋ํด์ ธ์ ๋์ด ์ด์ด์ง ์์๊ฐ์ฒด std::string("hello world")๊ฐ ์์ฑ๋๋ค. ์ฌ๊ธฐ๊น์ง ์ข๋ค. ๊ทธ๋ผ
std::string s3 = std::string("hello world");
์ ํํ๊ฐ ๋๋ค.
๊ทธ๋ผ ์ ์์๊ฐ์ฒด์ ๊ฐ์ ๋ณต์ฌํด๊ฐ๊ธฐ ์ํดย ๋ณต์ฌ์์ฑ์๊ฐ ํธ์ถ๋๊ณ ์ ๊ฐ๋ค์ ์ ๋ถ ๋ณต์ฌํด๊ฐ ๊ฒ์ด๋ค.
๋น์ฅ ์ ๊ธธ์ด๋ผ๋ฉด ์๊ด์์ง๋ง, ์์๊ฐ์ฒด๊ฐ ์ ๊ฒ๋ณด๋ค ํจ์ฌ ํฌ๋ค๋ฉด ์ด๊ฑด ๋ฌธ์ ๊ฐ ๋๋ค.
ํ์ง๋ง ์ด์ ์ฐ๋ฆฌ์๊ฒ ๋ฌด๋ธ ์๋งจํฑ์ด ์๋ค.
s+s2์ ๊ฒฐ๊ณผ๋ฌผ์ ์ค๋ฅธ๊ฐ์ด๋ค.
๊ทธ๋ฌ๋ฏ๋ก ์ด๋์์ฑ์๊ฐ ํธ์ถ๋ผ์ s+s2์ ๊ฒฐ๊ณผ๊ฐ์ด ๋ญ๋น์์ด s3์๊ฒ ์ ๋์ด๊ฐ๋ค.
๊ทธ๋ฆฌ๊ณ ์ด๋ฐ ์ฑ๋ฅ์ ํฅ์ ๋นผ๊ณ ๋, ์ด ๋ฌด๋ธ์๋งจํฑ์ ํ๋์ ์ฅ์ ์ด ๋ ์๋ค.
๋ฌด๋ธ์๋งจํฑ์ ๋ง ๊ทธ๋๋ก ์ด๋์ด๋ค.
๊ฐ์ด ์๋์ ์๋ ๊ฒ์ด ์๋ก ๊ฐ๋ฉด, ๊ทธ ๊ฐ์ ์์๋ง ์กด์ฌํ๋ค. ์๋์๋ ์กด์ฌํ์ง ์๋๋ค.
๊ทธ๋ฌ๋ฏ๋ก ์ด๋์ ๋์์ ์๋ฏธ๋ก ์ ์ผ๋ก ์ ์ผ์ฑ(unique)์ ๋ณด์ฅํ๋ค. ๋ณต์ฌ์ ๋ค๋ฅด๊ฒ.
๊ทธ๋์ ์ค๋งํธํฌ์ธํฐ std::unique_ptr ๊ฐ์ ๊ฒฝ์ฐ๋ ์ด๋ฐ ์ด๋๋ง์ ํํ ์ ์๋ค. ๋ณต์ฌ๋ ๊ธ์ง๋์ด์๋ค.
์ด ์ธ์๋ ๋ณต์ฌ๋ ๊ธ์งํ๊ณ ์ด๋๋ง์ ํ๊ฐํ๋ ํด๋์ค๋ค์ด ๊ฝค ์๋ค.
auto p = std::make_unique
std::unique_ptr
std::unique_ptr
์ ๊ทธ๋ฆฌ๊ณ ์ค๋ฅธ๊ฐ์ฐธ์กฐ๊ฐ ๋ฑ์ฅํ๋ฉด์ ์๋ 4๊ฐ์๋ ํด๋์ค์ ๊ธฐ๋ณธ ํจ์๋ค์ด, 6๊ฐ๋ก ๋์ด๋ฌ๋ค.
ํด๋์ค๋ช
์ด T์ผ ๊ฒฝ์ฐ, ๊ธฐ๋ณธ ํจ์๋ค์ ์๋์ ๊ฐ๋ค.
**T()=default; **//๊ธฐ๋ณธ ์์ฑ์
~T() = default; //์๋ฉธ์
T(const T&) = default; //๋ณต์ฌ์์ฑ์
**T(T&&) = default; **//์ด๋์์ฑ์
**T& operator=(const T&) = default; **//๋ณต์ฌ๋์
์
**T& operator=(T&&) = default; **//์ด๋๋์
์
์ด๋์์ฑ์์ ์ด๋๋์
์๋ ๊ตฌํํ ํ์๊ฐ ์๋ค. ๋ณต์ฌ์์ฑ์์ ๊ฐ์ ์์๋ณต์ฌ์ ๋ฌธ์ ๋ ์๊ธฐ ๋๋ฌธ์ ๊ทธ๋ฅ =default๋ง ํด์ค๋ ๋๋ค.(์ปดํ์ผ๋ฌ์๊ฒ ์๋๊ตฌํ์ํค๊ธฐ)
๊ทธ๋๋ ๋ง์ฝ ๊ตฌํํ๊ณ ์ถ๋ค๋ฉด, ์๋์ฒ๋ผ ํ๋ฉด ๋๋ค.
//๊ฐ์ : ํ์
T์๋ ๋ฉค๋ฒ๋ณ์๋ก a์ b๋ฅผ ๊ฐ์ง๋ค.
//๊ฐ์ : a์ b๋ ์ ๋ถ ์ด๋์ด ๊ฐ๋ฅํ๋ค.
T(T&& other) :
a(std::move(other.a)),
b(std::move(other.b)
{}
T& operator=(T&& other)
{
ย ย ย this->a=std::move(other.a);
ย ย ย this->b=std::move(other.b);
ย ย ย return *this;
}
์๋ฌดํผ ์ค๋ฅธ๊ฐ ์ฐธ์กฐ๋ ๊ต์ฅํ ์ ์ฉํ๋ค.
๋ฌธ์ ๋ ์์ํ ๊ท์น๊ณผ ํจ์ ์ด ๋ง๊ณ , ๋ณต์กํ๋ค๋ ๊ฒ์ธ๋ฐ
๊ฐ์ฅ ํท๊ฐ๋ฆด๋งํ ๊ฒ์, ์ค๋ฅธ๊ฐ ์ฐธ์กฐ์๋ ์ค๋ฅธ๊ฐ์ด ์๋๋ผ๋ ๊ฒ์ด๋ค. ์ค๋ฅธ๊ฐ ์ฐธ์กฐ์ ์์ฒด๋ ์ด๋ฆ๋ ์๊ณ , ์ฃผ์์ฐ์ฐ๋ ๊ฐํ ์ ์์ผ๋ฉฐ, ํํ์์ด ์ข
๋ฃ๋์ด๋ ์์กดํ๋ค.
๋๋ฌธ์ ์๋์ ๊ฐ์ ๊ฒฝ์ฐ๋ ์ด๋์ด ๋ฐ์ํ์ง ์๋๋ค.
std::string s = "...";
std::string&& s2 = std::move(s); //s->s2 ์ด๋
std::string s3 = s2; //s2->s3 ์ด๋ ์คํจ. ๊ทธ๋ฅ ๋ณต์ฌ ์์ฑ์ ํธ์ถ
์ด๋์ ๊ณผ์ ์ ์์ํ๊ฒ ์ค๋ฅธ๊ฐ์ผ๋ก๋ง ์ ๋ฌ๋์ด์ผ ํ๋ค.
์๋์ ๊ฐ์ด ๊ณ ์น๋ฉด ์ด๋์ด ์ํ๋๋ค.
std::string s = "...";
std::string&& s2 = std::move(s); //s->s2 ์ด๋
std::string s3 = std::move(s2); //s2->s3 ์ด๋
๊ทธ๋ฆฌ๊ณ ์ค๋ฅธ๊ฐ ์ฐธ์กฐ์๋ const๋ฅผ ๋ถ์ด๋ฉด ์๋๋ค.
์๋ฌ๋ ๋์ง ์์ง๋ง ์ด๋์ด ์คํจํ๋ค.
๋ ์์ธํ ์ฌํญ๋ค์ ๋ชจ๋ ์ดํํฐ๋ธ C++๋ฅผ ์ฐธ์กฐํ๊ธธ ๋ฐ๋๋ค.