2016-10-11 98 views
-1

我想在我的打印功能中創建一個臨時變量'p'。 我收到一個編譯器錯誤和2個警告,我不知道該如何處理。C++ - 鏈接列表 - 無法創建一個臨時節點

大多數功能在稍後有一個處理打印功能的時候纔會被填寫。

我也重新定義了cout < < & n打印出鏈接列表的值。

unique_ptr.h||In instantiation of 'typename std::_MakeUniq<_Tp>::__single_object std::make_unique(_Args&& ...) [with _Tp = Node; _Args = {const std::unique_ptr<Node, std::default_delete<Node> >*}; typename std::_MakeUniq<_Tp>::__single_object = std::unique_ptr<Node>]':| 

Deque.cpp|46|required from here| 

/usr/include/c++/6/bits/unique_ptr.h|787|error: invalid conversion from 'const std::unique_ptr<Node>*' to 'int' [-fpermissive]| 
Node.h|15|note: initializing argument 1 of 'Node::Node(int)'| 

|| ===建立失敗:1個誤差(S),2警告(S)(0分鐘0秒)=== |

Main.cpp的

#include <iostream> 
#include "Node.h" 
#include "Deque.cpp" 

using std::cout; 
using std::endl; 


std::ostream& operator<<(std::ostream& out, const Node& n) { 
    return out << &n << ": " << n.val << " -> " << n.next.get(); 
} 

int main() 
{ 

     return 0; 
} 

Node.h

#ifndef NODE_H 
#define NODE_H 

#include <iostream> 
#include <memory> 

class Node { 
public: 
Node(const Node& n) : val{n.val}, next{} 
    { 
    } 
Node(int v, std::unique_ptr<Node> n) : val{v}, next{move(n)} 
    { 
    } 
Node(int v) : val{v} 
    { 
    } 

private: 
    int val = 0; 
    std::unique_ptr<Node> next = nullptr; 

    friend class Deque; 
    friend std::ostream& operator<<(std::ostream&, const Node&); 
}; 

#endif 

Deque.h

#include <memory> 

class Deque{ 
    public: 
     Deque() = default; 
     Deque(const Deque&); 
     ~Deque(); //must use constant space 
     Deque& operator=(const Deque&); //we can use assignment in this assignement lols. 



     void print_queue(const std::string& label) const; //prints all nodes in queue, 
     //together with pointers to head and tail and also size of queue. 
     //routine calls the node output function - not tested 



    private: 
     std::unique_ptr<Node> head; 
     std::unique_ptr<Node> tail; 

    friend Node; 


}; 

Deque.cpp

#include "Deque.h" 
#include <memory> 
using std::cout; 
using std::endl; 


void Deque::print_queue(const std::string& label) const 
{ 
std::unique_ptr<Node> p = std::make_unique<Node>(&head); 
cout<< "This is the linked list: " << endl; 

while (p != NULL) 
    { 
     cout<< &head; 
    } 

} 
+0

我也試着'的std ::的unique_ptr P =頭;'這導致一個不同的錯誤'使用刪除功能的std「::的unique_ptr <_Tp, _Dp> ::的unique_ptr(常量的std ::的unique_ptr <_Tp, _Dp>&)'雖然我覺得這種方式比前者更合適。 – TigerCode

+0

代碼太多了。請將其縮小到最小的,自包含的,可編譯的示例,它仍然會重現錯誤。 – GManNickG

+0

會做,謝謝。 - 行爲已經完成。 – TigerCode

回答

1

看看你的代碼有兩件事我認爲你應該更多地閱讀。 第一個參考文獻和C++中&運算符的多重含義。

當你有這樣的功能:

void f(const Type& param); 

這意味着param是一個const Type參考。本例中的&聲明param作爲參考。如果你想調用這個方法,你像這樣做:

Type value; 
f(value); 

注意參數value被原封不動的使用,沒有任何其他限定。相反,如果你試圖調用的功能等:

f(&value); 

那麼&意味着address of&value不是一個參考,這是一個指針,這就需要功能看起來像:

void f(Type *param); 

這就解釋

std::unique_ptr<Node> p = std::make_unique<Node>(&head); 

這裏head是:當你寫這樣你得到的錯誤210所以&head是指向unique_ptr<Node>的指針。這正是該錯誤消息告訴你:

invalid conversion from 'const std::unique_ptr<Node>*' to 'int' 

它試圖調用Node構造服用int參數並不能指針轉換爲unique_ptrint

你應該更多地閱讀的第二件事是unique_ptr本身。總之,unique_ptr是一個單一所有權的智能指針,它不能被複制,你不能管理同一個對象。 這就是爲什麼你不能這樣做在你的代碼:

std::unique_ptr<Node> p = head; 

在這種情況下,該錯誤消息主要是告訴你那裏是unique_ptr沒有拷貝構造函數。

因爲你不能複製unique_ptr s,遍歷一個鏈表實現了你寫的方式,它不能像通常的做作業一樣完成你想要做的功課。你還必須當你在列表中實施其他操作時,比較難以考慮,比如插入或刪除節點。

但讓我們堅持遍歷列表。您不能複製unique_ptr,因此您必須使用引用或原始指針訪問它們。

使用引用

這種方法也並不簡單,因爲引用不能被他們定義後,「重新分配」。所以,你可以嘗試遞歸做到這一點,例如:

void printNodeAndGoNext(const std::unique_ptr<Node> &node) 
{ 
    if (node) 
    { 
     std::cout << node->value; 
     printAndGoNext(node->next); 
    } 
} 

void print() 
{ 
    printNodeAndGoNext(head); 
} 

這僅使用引用unique_ptr S,它並不需要創建節點的任何副本。 但與遞歸函數一樣,它不會縮放。不要這樣做。

使用指針

您可以使用原始非所屬指針要麼unique_ptrš自己或他們管理的基本節點。

第一個版本是這樣的:

void print() 
{ 
    const std::unique_ptr<Node> *node = &head; 
    while(node) 
    { 
     std::cout << (*node)->value; 
     node = &((*node)->next); 
    } 
} 

,請注意* S和& S和你得到的實際數據類型。

第二個版本,使用原始指針到實際的節點:

void print() 
{ 
    const Node *node = head.get(); 
    while (node) 
    { 
     std::cout << node->value; 
     node = node->next.get(); 
    } 
} 

所有這些之間,最後一個版本將是優選的。如果你有點小心,使用原始非擁有指針指向由擁有unique_ptr所管理的對象是非常好的和安全的。

免責聲明

上面的代碼片段只是爲了說明的點,你必須去適應的想法和實際編寫適合自己情況的代碼。

未來的問題,您將面臨

我已經提到過其中的一些。您必須使用unique_ptr的獨特屬性實施標準列表操作,如插入和刪除。

思考(和修復)的另一個方面與遞歸有關。更具體地說,當你有一個像這樣實現的列表,並且有更多的幾個節點(數千個節點,幾萬,幾百萬等)並且你想銷燬它時會發生什麼?