2016-10-16 12 views
1

실제로 여기에 질문을 게시하는 것은 이번이 처음입니다! 단일 링크 된 목록에 대한 복사 생성자를 만드는 데 문제가있었습니다. 나는이 사이트와 다른 여러 사이트에서 비교할만한 예제를 찾기 위해 높거나 낮게 검색했습니다. 스마트 포인터를 사용하려고 시도했지만 지금까지는 unique_ptr(s) 만 사용했습니다. 이 함수는 전달 된 링크 된 목록의 전체 복사본을 만들기위한 것입니다. 나는 지금까지 다음과 같은 시도를했지만 단지 세그 폴트를 얻는다. 몇 가지 테스트를 실행했으며 내 insert_front()insert_back() 기능이 정상적으로 작동한다고 생각합니다. 그게 도움이된다면 나는 머리와 꼬리 모두에 대한 포인터를 가지고있다. 다음은 내가 시도한 코드이다.스마트 포인터를 사용하여 단일 연결 목록에 대한 복사 생성자를 구현하는 방법

Deque::Deque(const Deque& deque2copy){ 
    this -> head = 0; 
    unique_ptr<Node> temp = make_unique<Node>(deque2copy.head -> val, move(deque2copy.head->next)); 
    while(temp != 0){ 
     this ->insert_back(temp->val); 
     temp = move(temp-> next); 
    } 
} 

업데이트 # 1

Deque::Deque(const Deque& deque2copy){ 

    if(deque2copy.head->next == nullptr){ 
     return; 
    } else { 
     this -> head = 0; 
     unique_ptr<Node> temp = make_unique<Node>(*deque2copy.head->next); 
     while(temp != 0){ 
      this ->insert_back(temp->val); 
      temp = move(temp-> next); 
     } 
    } 

} 
+2

왜 복사중인 컨테이너에서 이동하고 있습니까? 그것은'auto_ptr'입니다. 직관적이지 않은 – krzaq

+0

은'move()'없이 컴파일 된 것처럼 보입니다. 'unique_ptr'을 복사 할 필요가 있다고 생각 했습니까? – Shrayan

+1

이동을 사용하면 이동이 가능합니다. 이동하면 더 이상 원본을 얻지 못합니다. 난 당신이'make_unique 싶었던 것 같아요. – krzaq

답변

0

당신은 당신의 Deque 또는 Node 클래스가 실제로 정확히처럼 보이는 방법에 대한 많은 정보를 게시하지 않았다. 코드 스 니펫에서 훑어 본 정보를 기반으로 할 때 주된 문제는 std::unique_ptr<T>을 사용하여 목록을 탐색한다는 것입니다. 작동하지 않습니다. std::unique_ptr<T>이 할당되거나 소멸 될 때마다 보유 된 객체가 해제됩니다. 비 소유 포인터가 필요합니다.

당신은 많은 컨텍스트 정보를 게시하지 않았기 때문에 내가 쉽게이 코드가 작동하는지 테스트 할 수 있지만, 나는 그것이 잘되어야 가정 것 :이 코드는 비 사용하여 두 목록을 탐색

Deque::Deque(const Deque& deque2copy) 
    : head() { // the default constructor does the null-initialization 
    std::unique_ptr<Node>* tail(&this->head); 
    for (Node* temp(deque2copy.head.get()); temp; temp = temp->next.get()) { 
     *tail = std::make_unique<Node>(temp->value); 
     tail = &tail->next; 
    } 
} 

하는 것으로 -owning 포인터 : 그것은 할당 또는 std::unique_ptr<Node> 파괴시 Node 오브젝트 파괴 방지하기 std::unique_ptr<Node>::get()로부터 얻어지는 Node* 사용 소스 목록

  • .
  • 대상 목록의 현재 std::unique_ptr<Node>에 대한 tail 포인터 (처음에는 head이고 마지막에 next 포인터가 할당 된 후이 포인터가 효율적으로 노드를 추가합니다).

코드에는 Node에 생성자 인수가 value 인 것으로 가정합니다. 이 생성자가 따라하여 value 멤버를 초기화 할 및 기본 초기화 next 회원, 예를 들면 :

Node::Node(T const& value) 
    : value(value) 
    , next() { 
} 

목록의 요소를 소유 포인터를 사용하는 것은 좋은 생각이 일반적으로 양해하여 주시기 바랍니다 : 머리의 소멸자는 재귀 것이다 목록에있는 모든 노드의 소멸자를 호출하십시오. 소멸자가 실제로 작성된 방법에 따라이 재귀는 스택 오버플로를 쉽게 만들 수 있습니다. 이 재귀를 피하려면 목록에 사용자 정의 소멸자를 작성해야합니다. 그러나 이렇게하면 노드가 시작되도록 유지하기 위해 std::unique_ptr을 사용하는 목적을 완전히 상실하게됩니다.