2012-08-03 2 views
7

클래스에 대한 이동 시맨틱 구현에 꽤 많은 시간을 할애했지만, 이제는 그것을 사용하는 함수를 다루고 있습니다.시맨틱과 const 레퍼런스 이동하기

좋아요, 그래서이 개체에는 힙에 많은 데이터가 있습니다 : CLargeOb에 대해 이동 구문 (생성자 및 연산자 =)을 구현했습니다. 이 객체가 휴지통/이동 될 수 있도록하는 것이 항상 가능한 것은 아니다 그러나

void OtherOb::Func(CLargeOb&& largeOb1, CLargeOb&& largeOb2) 
{ 
    SomeOtherFunc(largeOb1); // use objects 
    SomeOtherFunc(largeOb2); 
    m_largeOb1 = (CLargeOb&&)largeOb1; // save as members and trash the originals 
    m_largeOb2 = (CLargeOb&&)largeOb2; 
} 

, 그래서 나는이 두 가지 기능을 추가 : 그것은 이상적으로 다음과 같이 사용된다 당신이 이미 수, 작동하지만

void OtherOb::Func(const CLargeOb& largeOb1, CLargeOb&& largeOb2) 
{ 
    SomeOtherFunc(largeOb1); 
    SomeOtherFunc(largeOb2); 
    m_largeOb1 = largeOb1; 
    m_largeOb2 = (CLargeOb&&)largeOb2; 
} 

void OtherOb::Func(CLargeOb&& largeOb1, const CLargeOb& largeOb2) 
{ 
    SomeOtherFunc(largeOb1); 
    SomeOtherFunc(largeOb2); 
    m_largeOb1 = (CLargeOb&&)largeOb1; 
    m_largeOb2 = largeOb2; 
} 

을 이 객체를 매개 변수로 3 개 이상 사용하는 함수가있을 때 * ss에서 큰 고통이 될 것 같아요 ... 템플릿을 사용하거나 '완벽한 전달'을 사용하여이를 해결하는 영리한 방법이 아닌가요?

+0

@MooingDuck : VS2010에서 문제없이 작동합니다. 연산자 = (&&)를 호출하려면 std :: move 또는 && cast를 사용하여 명시 적으로 호출해야합니다. 그러나 솔루션은 물론 그 아래 훨씬 더 물론 제공했다. – demorge

+0

@demorge : 오 맞아요. 이름이 지어지면 규칙이 변경된다는 것을 완전히 잊어 버렸습니다. 죄송합니다 –

+1

'(CLargeOb &&) largeOb1' 대신'std :: move (largeOb1)'을 써주십시오. 프로그래머 세대는 비 관용적이고 경계선을 읽을 수없는 C/C++ 믹스 대신 표준 C++ 11 이동 방법을 사용해 주셔서 감사합니다. – fredoverflow

답변

15

C++ 03의 경우와 마찬가지로 가이드 라인은 입니다. 사본을 원하면 매개 변수 목록에서 확인하십시오.

이 개체를 얻는 방법에 발신자 거래를 할 수 있습니다, 당신은 단지에 관계없이 객체를 얻을 :

void OtherOb::Func(CLargeOb largeOb1, CLargeOb largeOb2) 
{ 
    SomeOtherFunc(largeOb1); // use objects 
    SomeOtherFunc(largeOb2); 
    m_largeOb1 = std::move(largeOb1); // save as members and trash the originals 
    m_largeOb2 = std::move(largeOb2); // (you should use std::move, not cast) 
} 

발신자 :

OtherOb o; 

CLargeOb x, y; 
const CLargeOb z; 

o.Func(x, std::move(y)); // need x for later, done with y so move it 
o.Func(std::move(x), z); // done with x, necessarily copy z 

이 여러 전문 과부하만큼 효율적입니다. 왜? 이들은 이미 생성자로 클래스에 존재하므로입니다. 컴파일러가 콜 사이트에서 호출 할 전화 번호를 파악하게하십시오. 이미 수행해야 할 일을 알고 있습니다.

+2

나는 그것을 매우 간단하게 좋아한다! – demorge

+0

한 번이 아니라 두 번 움직이지 않습니까? (주의 : 물론 추가 이동은 거의 눈에 띄지 않아야합니다. 그래서 어쨌든 upvoted했습니다.) – Sjoerd

+0

@Sjoerd : 예, 컴파일러가 어딘가에서 벗어날 수 있기를 바랍니다. 그리고 말하지 않았더라도, 그건 중요하지 않아야합니다. – GManNickG