2013-04-14 3 views
0

지난 1 시간 동안이 코드에 갇혀 있었지만 여전히 스마트 포인터를 머리에 쓰고 구현하려고했지만이 문제로 인해 꽤 어려움을 겪었습니다.문제 전달 std :: unique_ptr의

내가 듣고있는 오류 메시지는 다음과 같습니다.

'std::unique_ptr<_Ty>::unique_ptr' : cannot access private member declared in class 'std::unique_ptr<_Ty>' 

답변

1

값으로 unique_ptr을 전달할 수 없습니다. 금지 된 unique_ptr의 복사본을 만들려고 다음과 같습니다

if(gameObject->isCollidable()){ 
    _actors.Add(gameObject);  // THIS LINE 
} else { 
    _props.Add(gameObject);  // and THIS LINE 
} 

해결책이 std::move()으로 전달하고이 두 개의 소유권 이전에 발생합니다

if(gameObject->isCollidable()){ 
    _actors.Add(std::move(gameObject)); 
//    ^^^^^^^^^ 
} else { 
    _props.Add(std::move(gameObject)); 
//    ^^^^^^^^^ 
} 

. 하나는 의 입력 매개 변수이고 std::pair의 하나는 _gameObjectsstd::unique_ptr<Entity>입니다.

는 또 다른 해결책은 참조 얻기 위해 GameObjectManager::Add의 서명을 수정하는 것입니다

: 현재하고있는 것처럼 이제

void GameObjectManager::Add(std::unique_ptr<Entity> & gameObject) 
//             ^^^ 

, 당신은 메서드를 호출 할 수 있습니다, 이것은에 (단일 소유권 이전에 발생합니다 pair in _gameObjects).

그러나 주석에서 @Xeo가 지적한대로 두 번째 옵션은 우수 사례 원칙을 위반합니다. 소유권 이전은 모든 지점에 명시되어야합니다.

+3

소유권 이전은 모든 지점에서 명시되어야합니다. – Xeo

+0

Xeo를 어떻게 사용합니까? 참조 방법을 사용하는 것이 나쁜 progrmaming일까요? – user1725794

+0

@ user1725794 : 미묘합니다. 고유 포인터의 소유권 이전은 항상 명시 적이어야합니다. 이 방법으로 고유 한 포인터를 공유하는 두 개의 루틴으로 끝나며, 어떤 종류의 'unique_ptr'(즉, 한 번에 * one * 엔티티에 의해 소유되어야 함)의 목적을 무효화합니다. Btw, 일부 사용자에게 알리려면 사용자 이름 앞에'@'문자를 사용해야합니다. –

3

당신은 std::move를 사용하여 AddaddEntity에서 소유권을 전달해야합니다 : 당신은 명시 적으로는 이동할 수 있도록없이 unique_ptr를 전달할 수 없습니다

if(gameObject->isCollidable()){ 
    _actors.Add(std::move(gameObject)); 
} else { 
    _props.Add(std::move(gameObject)); 
} 

. 이것이이 포인터를 고유 포인터로 만드는 이유입니다. 복사 할 수 있으면 원본과 복사본이 같은 개체를 가리키고 있습니다. 그것으로부터 이동할 때, 원래 포인터는 새로운 포인터에 소유권을 포기합니다.

+1

그리고 명시 적으로 이동을 허용하면 더 이상 복사되지 않습니다. P – Xeo

+0

아, 끝내 주네! 수정 해 주셔서 감사합니다! – user1725794

+0

@Xeo 좋은 지적! –

1

당신은받는 함수에 unique_ptr좌변을 통과하려고되어 그 포인터의 사본를 만드는 초래 값에 의해 unique_ptr이 의도적으로 금지되어 있습니다. 고유 포인터는 고유 한 소유권을 모델링하기위한 것입니다. 이는 고유 포인터를 보유하는 엔티티가 뾰족한 객체의 소유권을 가짐을 의미합니다.

고유 한 포인터를 주위에 복사하는 것은 시스템 전체에 여러 개의 소유 포인터가 퍼져있는 것을 의미합니다. 물론 고유 한 포인터의 고유 한 목적을 상실하게되는 것은 물론 고유 포인터를 복사 할 수없는 이유를 설명합니다.

당신이 할 수있는 것은 이전이 소유하는 것입니다, 그래서 당신은 그 함수에 인수로 전달 할 때, 당신은 할 수 이동unique_ptr 고유 포인터를 허용하는 함수를 호출하는 경우 :

_actors.Add(std::move(gameObject)); 
//   ^^^^^^^^^ 

으로 소유권을 이전하면이 고유 한 포인터에서 사라진다는 것은 이전에 가리킨 대상을 소유하지 않은 "좀비"고유 포인터 개체가 호출자 기능에 남아 있음을 의미하므로 호출자 함수는 더 이상 참조를 취소하려고하지 마십시오.

관련 문제