이전 회에서 이야기 했던 것을 토대로 이번에는 코드로 그것을 보여드리도록 하겠습니다. 이전 글에서 알쏭달쏭 했던 분들은 앞으로 보여줄 코드를 보면 앞의 설명에 대해서 이해할 수 있을 것입니다.
첫 번째 글이 지루하고 애매했다면 두 번째 글부터 아주 흥미롭고 중요한 이야기가 나옵니다.
Move
생성자와 Move 대입 연산자
기존의 class에서는 복사 생성자와 대입 연산자만 정의할 수 있었지만 RValue Reference에 의해 ‘Move 생성자’와 ‘Move 대입 연산자’라는 것이 생겼습니다.
< Code 1. QuestInfo 클래스 >
class QuestInfo
{
public:
// 복사 생성자
QuestInfo(const QuestInfo&
quest)
: Name(new char[quest.NameLen]),
NameLen(quest.NameLen)
{
memcpy(Name, quest.Name,
quest.NameLen);
}
// 대입 연산자
QuestInfo& operator=(const QuestInfo&
quest)
{
if (this != &quest)
{
if (NameLen < quest.NameLen)
{
// 버퍼를 확보한다
}
NameLen = quest.NameLen;
memcpy(Name, quest.Name,
NameLen);
}
return *this;
}
// Move 생성자
QuestInfo(QuestInfo&&
quest)
: Name(quest.Name),
NameLen(quest.NameLen)
{
quest.Name = NULL;
quest.NameLen = 0;
}
// Move 연산자
QuestInfo& operator=(QuestInfo&&
quest)
{
if( this != &quest )
{
delete Name;
Name =
quest.Name;
NameLen = quest.NameLen;
quest.Name =
NULL;
quest.NameLen = 0;
}
return *this;
}
private:
char*
Name;
int NameLen;
};
C++0x 이전에는 없던 것이
Move 생성자 QuestInfo(QuestInfo&&
quest)와 Move 대입 연산자 QuestInfo& operator=(QuestInfo&&
quest)입니다.
외견 상으로 기존의 복사 생성자, 대입 연산자와의 차이는 함수 파라메터에서 ‘&’가 아닌 ‘&&’을 사용하는 것입니다.
성능이 좋아진다고 했는데….
RValue Reference를 설명할 때 이것 덕분에 프로그램의 성능이 좋아진다고 했습니다.
왜 그럴까요? <Code 1>에서 복사 생성자와 Move 생성자, 대입 연산자와 Move 대입 연산자의 구현을 잘 보세요. 다르지 않나요?
RValue Reference는 Move Semantics에 의해 복사가 아닌 메모리 이동이라는 것을 할 수 있습니다. <Code 1>의 Move 생성자와 Move 대입 연산자는 넘겨 받은 인자를 복사하지 않고 메모리 상의 이동을 하고 있습니다.
< Code 2. 복사 생성자와 Move 생성자 >
// 복사 생성자
QuestInfo(const QuestInfo&
quest)
: Name(new char[quest.NameLen]),
NameLen(quest.NameLen)
{
memcpy(Name, quest.Name,
quest.NameLen);
}
// Move 생성자
// Move 생성자
QuestInfo(QuestInfo&&
quest)
: Name(quest.Name),
NameLen(quest.NameLen)
{
quest.Name = NULL;
quest.NameLen = 0;
}
복사 생성자는 new로 메모리 할당을 한 후 메모리 복사를 하지만, Move 생성자는 메모리 이동을 하고 있습니다.
크기가 작은 오브젝트에서는 큰 의미가 없지만 크기가 큰 오브젝트에서는 그 차이가 무시할 수 없을 것입니다.
RValue
Reference와 LValue Reference는 언제 사용할까요?
RValue Reference와 LValue Reference(기존의 참조)는 언제 사용하는지 구분 할 수 있으시나요?
RValue Reference가 생김으로 참조에 관한 룰이 좀 더 추가 되었습니다. 또한 이 두 개의 참조에 대해서 정확하게 알기 위해서는 참조에 대해서 좀 더 세세하게 알아야 됩니다.
그래서 어떤 사람들은 RValue Reference가 좋기는 하지만 이것 때문에 가뜩이나 복잡한 C++이 더 복잡하게 되었다고 불평하기도 합니다.
글이 좀 길어져서 RValue Reference가 사용되는 경우에 대한 것은 다음 글에서 코드로 보여드리겠습니다.
ps :
RValue Reference에 대해서 상세하게 알고 싶은 분들은 Microsoft의 VC++ 팀 블로그에 포스팅 된 글을 보시기를 바랍니다(영어이고, 내용도 길고, 좀 복잡해서 한번에 팍 하고 이해는 안될 수 있습니다).
http://blogs.msdn.com/vcblog/archive/2009/02/03/rvalue-references-c-0x-features-in-vc10-part-2.aspx
혹시 위 글을 꼭 알고 싶은데 영어 때문에 난감하고, 시간이 부족하니 정리해 주기를 바라는 분이 있다면 댓글로 알려주시면 뒤에 제가 이 글을 정리해서 올려보겠습니다.
'C++0x' 카테고리의 다른 글
| [VC++] 7. 우측 값 참조( RValue Reference ) - 네 번째 (3) | 2009/05/20 |
|---|---|
| [VC++] 6. 우측 값 참조( RValue Reference ) - 세 번째 (0) | 2009/05/09 |
| [VC++] 5. 우측 값 참조( RValue Reference ) – 두 번째 (2) | 2009/05/06 |
| [VC++] 4. 우측 값 참조( RValue Reference ) - 첫 번째 (2) | 2009/05/04 |
| [VC++] 3. static_assert (0) | 2009/04/27 |
| [VC++] 2. C++0x의 auto (6) | 2009/04/23 |




댓글을 달아 주세요
재밌게 잘 봤습니다. 코딩 안 한지가 오래되어서 가물가물 거리네요.. ㅡㅡ;
부족한 글인데 좋게 봐주셨어 고맙습니다.^^
코딩은 손 놓으면 감 잠는데 시간이 살짝 걸리죠