链表-无法创建临时节点



我试图在我的打印函数中创建一个临时变量'p'。我得到一个编译器错误和两个警告,我不知道如何处理。

一旦我有了print函数的句柄,大多数函数就会被遗漏,以便稍后填充。

我还重新定义了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分钟(s), 0秒(s)) = = = |

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;
    }
}

看看你的代码,我认为你应该多读两件事。首先是引用和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);

这里headstd::unique_ptr<Node>,所以&head是指向unique_ptr<Node>的指针。这就是错误信息告诉你的:

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

它试图调用Node构造函数,接受int参数,无法将指针从unique_ptr转换为int

您应该更多地了解的第二件事是unique_ptr本身。简而言之,unique_ptr是一个单所有权智能指针,它不能被复制,你不能让unique-ptr管理同一个对象。这就是为什么你不能在你的代码中这样做:

std::unique_ptr<Node> p = head;

在这种情况下,错误信息基本上告诉你没有unique_ptr的复制构造函数。

因为你不能复制unique_ptr s,所以用你写的方式遍历一个链表就不能像你平时做作业那样做了。在实现列表上的其他操作(如插入或删除节点)时,您还必须更加仔细地考虑。

但是让我们坚持遍历列表。你不能复制unique_ptr s,所以你必须使用引用或原始指针来访问它们。

使用引用

这个方法也不直接,因为引用在定义后不能"重新分配"。所以你可以尝试递归地做,例如:

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 s管理的对象是完全可以的,如果你稍微小心的话。

免责声明

上面的代码片段只是为了说明要点,你必须适应这些想法,并根据你的情况实际编写代码。

未来面临的问题

我已经提到了其中的一些。您必须使用unique_ptr的独特属性来实现标准的列表操作,如插入和删除。

另一个需要考虑(和修复)的方面又与递归有关。更具体地说,当你有一个这样的列表,它有更多的节点(数千个节点,数万个,数百万个等等),你想要摧毁它会发生什么?

相关内容

  • 没有找到相关文章

最新更新