/*
Move Constructor( 이동 생성자 )
c++0x 에는 r-value reference의 도입으로 인해서 Move Constructor가 생겼다.
이동 생성자의 특징은 복사 대상의 데이터를 지우는 소유권 이전 방식이다.
기존에 있던 reference는 그래서 이름이 l-value reference 로 불린다.
l-value 와 r-value 의 차이는 대입식에서 왼쪽에 오느냐, 오른쪽에 오느냐의 차이인데
간단히 말해서 l-value 는 변수라고 보면 되고, r-value는 상수라고 보면 된다.
기존에 l-value reference는 l-value들만, 즉 변수들만 가리킬 수 있는 반면에
r-value reference는 r-value 들만, 즉 상수들을 가리킬 수 있다.
int b = 3;
int& a = b;
int& c = 3; // error
int&& d = a; // error
int&& d = 3; // ok.
r-value reference가 사실 그냥 보기에는 이동 생성자와 전혀 무관해 보이는데, 이것은 기존에
복사 생성자로 표현하기 어색했던, 소유권 이전방식을 적절히 표현하기에 적합하다.
무슨 말이냐면, 기존에 auto_ptr 과 같은 소유권 이전의 스마트 포인터들은 값을 이동시키고 싶어하지만,
적절한 표현이 없어서, const를 제외시킨 아래와 같은 방식으로 구현을 했었다.
auto_ptr(auto_ptr& a)
문제는 이것이 복사하려는 것인지, 이동하려는 것인지에 대한 명확한 지표가 되기 힘들다는 것.
이 문제를 해결한 것이 r-value reference(&&)의 등장이다.
r
*/
#include
class MoveClass
{
public:
// Default Constructor
MoveClass() {
std::cout << "Default Constructor Call" << std::endl;
}
// Copy Constructor
MoveClass(const MoveClass& a) // 반드시 const로 해야 된다. 그렇지 않으면 Move Constructor가 제대로 호출되지 않는다.
{
std::cout << "Copy Constructor Call" << std::endl;
}
// Move Constructor
MoveClass(MoveClass&& a)
{
std::cout << "Move Constructor Call" << std::endl;
}
};
// 값이 복사되는 곳에서는 일반적으로 복사 생성자가 호출된다.
MoveClass foo(MoveClass& a)
{
MoveClass local;
return local; // 값이 복사 되는데, 우선순위가 존재한다.
// MoveClass(const MoveClass& a) 형태의 복사 생성자가 존재하고,
// MoveClass(MoveClass&& a) 형태의 이동 생성자가 존재하면
// 이동 생성자를 호출한다.
}
int main()
{
MoveClass a; // Default Constructor Call
foo(a);
MoveClass b(a); // Copy Consturctor call
MoveClass b(std::move(a)); // Move Constructor call
}