2017-11-25 19 views
2

나는 현재 C를 배우고 ++ 하나는 내가에 대한 혼란 스러워요하는 하나의 표준에 대한 이동 생성자를 트리거하는 것입니다이동 구문을 트리거하는 생성자는 무엇입니까?

//Code might be incorrect since I havent tested it out 
Xyt::ByteArray* Xyt::ResourceManager::LoadFileToByteArray(std::string Path) 
{ 
try { 
    std::ifstream FileStream(Path, std::ios::in); 
    std::ifstream::pos_type Pos = FileStream.tellg(); 

    FileStream.seekg(0, std::ios::beg); 

    std::vector<char> Buff(Pos); 
    FileStream.read(Buff.data(), Pos); 

    FileStream.close(); 

    //I want to trigger the move constructor here 
    return new Xyt::ByteArray(std::move(Buff)); 
} 
catch (std::exception e) { 
    std::cout << "ERROR::FILE::FILE_NOT_SUCCESFULLY_READ" << Path << std::endl; 
    return nullptr; 
    } 
} 

이동 :: 표준을 사용하는 올바른 방법 인 어느 대해 궁금해 :: 벡터? 그것은이 하나

Xyt::ByteArray::ByteArray(std::vector<char>&& Buffer) 
{ 
    this->Buffer = Buffer; 
} 

이 하나 (둘 다 표준 : 이동 (버프)와 버프를 받아) (발신자 나던 사용 표준 : 이동 때 오류를 컴파일)

인가?

Xyt::ByteArray::ByteArray(std::vector<char> Buffer) 
{ 
    this->Buffer = Buffer; 
} 

또는이 하나?

Xyt::ByteArray::ByteArray(std::vector<char> Buffer) 
{ 
    this->Buffer = std::move(Buffer); 
} 

제 1 생성자가 이동 의미 체계를 사용하는 올바른 방법이라는 것을 인터넷을 통해 알게되었습니다. 하지만 첫 번째 생성자를 사용하면 실제로 std :: vector Buff에 복사본을 만들려면 다른 생성자를 만들어야한다는 뜻인가요?

도움이 될 것입니다.

답변

2

유일한 작품은 세 번째입니다. 그러나 그 이유는 std::move내부에 생성자를 사용했기 때문입니다. 그리고 그것은 두 가지 움직임을 일으 킵니다 : 하나는 매개 변수를 채우고 하나는 매개 변수에서 값으로 채 웁니다.

이 작업을 수행하는 올바른 방법은 다음과 같습니다

Xyt::ByteArray::ByteArray(std::vector<char>&& Buf) 
    : Buffer(std::move(Buf)) 
{} 

이 한 번만 이동 작업을 호출합니다.

이동 작업을 호출하려면 명명 된 rvalue 참조에서 명시 적으로 이동해야합니다.


하지만 난이 표준 : : 벡터 버프에 사본을 실제로하려면 내가 다른 생성자를해야 그 의미 하는가 1 생성자를 사용하는 경우?

엄격하게 필수 사항은 아닙니다. 당신은 그들이 함수를 호출 할 때 복사 자체를 할 사용자를 요구할 수 :

Xyt::ByteArray(std::vector<char>(Buff)) 

을하지만 그래, 당신이 직접 좌변을 제공하기 위해 사용자를 원하는 경우, 당신은 좌변에서 복사 할, 당신은을 제공해야 생성자는 (const) 왼쪽 값 참조를 가져 와서 복사본을 수행합니다.

+0

알겠습니다. 그래도 한가지 더, Xyt :: ByteArray :: ByteArray (std :: vector && 버퍼) { this-> Buffer = std :: move (Buffer); }, 만약 std :: move가 이렇게하면 세 번째 생성자와 비슷한 두 번 move 생성자를 호출할까요? – Xyten

+1

@Xyten : 아니요. 이동 * 생성자 *를 전혀 호출하지 않습니다. 'ByteArray :: Buffer'는 그 시점에서 * 살아있는 객체이므로 move * assignment *를 호출 할 것입니다. 그래서 멤버 초기화 프로그램을 사용했습니다. 여기에 멤버의 초기화 *를 넣습니다. –