2010-12-10 4 views
0

좋아요, 저는 평범한 가치에 대해 읽었으며 훌륭한 아이디어처럼 보입니다.하지만 뭔가 계속 저를 귀찮게합니다. 특히 이동이라는 주장은 우리가 자원을 훔치고 복사를 피할 수있게합니다.rvalues ​​C++ 0x 및 힙으로 이동

이동이 작동하고 스택에서 일어나는 모든 작업에 대한 복사를 피할 수 있지만 결국 스택에서 수행되는 대부분의 작업은 힙에 복사 할 가치가있는 값을 산출하며 이것이 내가 생각하지 않는 부분입니다 움직이게.

주어진 INT는 움직임 할당 연산자를 가지고 다음 코드를 가정하면,이 예에 따라서

struct Foo 
{ 
int x; 
}; 

void doIt() 
{ 
Foo* f = new Foo(); 
f->x = (2 + 4); 
} 

를 상기 r- 수치 (2 + 4)의 결과가 아마 F- 넘어서 이동할 수> X 대신 복사 된 좋아, 좋아. 그러나 f와 결과적으로 f-> x는 에 있고 그 값은 스택에 있습니다. 사본을 피할 수없는 것처럼 보입니다. 당신은 단순히 r-> x가 r 값의 메모리를 가리킬 수 없습니다. 그 가치는 끝나자 마자 날아가 버릴 것입니다. 사본이 필요할 것 같습니다.

그래서 사본을 만들 수 있다고 생각합니까? 내가 틀린가요? 또는 rvalue 개념을 완전히 오해 했습니까?

+1

뭔가 오해하는 것 같습니다. 이동은 마법이 아니며 할당/복사하는 것보다 int 값을 가져 오는 더 빠른 방법이 없습니다. – UncleBens

+0

@UncleBens 글쎄, 나는 그것을 확인하려고하고있다. 나는 계속해서 rvalues를 읽으면 물건을 더 빨리 만들고 복사를 피한다. 그러나 나의 예에서와 같이, 필자는 실제로 복사가 필요하고 rvalues가 특정한 경우에만 도움이된다는 것을 확인하려고 노력하고있다. – anio

+0

스칼라 유형의 객체 이동은 해당 객체를 복사하는 것과 같습니다. 보다 복잡한 유형의 경우 이동이 흥미 롭습니다.이동하는 경우 정확히 무엇이 발생합니까? 클래스 디자이너가하는 일입니다. 자신의 이동 생성자를 정의하여이 동작을 제어합니다. – sellibitze

답변

5

이 경우 복사가 가능하지만 객체에는 int 만 포함되어 있기 때문에 그다지 문제가되지 않습니다.

일반적으로 개체가 힙에 할당 된 일부 데이터에 대한 포인터를 포함하는 경우 (개체 자체가 할당 된 위치에 관계없이) 걱정되는 시간입니다. 이 경우 해당 데이터의 새 복사본을 할당하는 것을 피하는 것이 좋습니다 (개체 자체가 스택에 있더라도 힙에 있으므로 개체 자체의 위치에 관계없이 이동할 수 있습니다).

+0

을 확인하십시오. 포인트. 한 힙 위치에서 다른 힙 위치로 리소스를 도용하는 데 Move를 사용할 수 있습니다. 그래서 우리는 stack-to-stack을 움직일 수 있습니다. 그리고 힙 - 힙 이동. 그러나 스택 - 힙 (heap-to-heap) 이동은 없습니다. 그게 내가 예상 한거야. – anio

+1

분명히 스택에서 힙으로 그리고 다른 방법으로는 객체를 이동할 수 있습니다. 이동 가능 유형은 일반적으로 어디에 살고 있는지 신경 쓰지 않습니다. 저장소 개념은 의미 이동과 직각을 이룹니다. – sellibitze

1

음. 지역 변수가 스택에 있습니다. 그 값은 6으로 최적화되고 결과 바이너리는 mov [dest], 6이 될 가능성이 큽니다.

3

나의 이해는 이동이 복사의 반대되지 않는 것입니다 : 대부분의 경우는 얕은 복사 (대신 딥 카피)를 구현하기 때문에 이동이 바람직하다.

개체가 일부 리소스에 대한 포인터를 보유하고 있으면 얕은 복사본이 포인터를 복사하는 반면 전체 복사본은 포인터가 가리키는 데이터를 복사합니다. 문제는 "우리가 얼마나 깊게 가야하는지"입니다. int 형의 얕은 또는 깊은 카피 같은 건 없다, 그래서 여기에 무관하다 :

귀하의 예는 단지 int 포함한다. 동적으로 할당 된 리소스가 관련되어있을 때만 움직이는 것이 맞다고 믿는 것은 당연합니다.

+0

이동은 확실히 얕은 사본으로 제한되지 않습니다. 이동 생성자는 클래스 디자이너에게 달려 있습니다. – sellibitze