首页 > 解决方案 > 我们不能在 C++ 中不使用指向对象的指针来创建节点吗?

问题描述

我在黑客等级的链接列表上解决了这个问题:https ://www.hackerrank.com/challenges/insert-a-node-at-the-head-of-a-linked-list/

并得到给定代码的正确答案。大部分代码都是预先编写好的;我只需要完成函数 insertNodeAtHead 函数(封闭在三颗星之间):

#include <bits/stdc++.h>
using namespace std;

class SinglyLinkedListNode {
    public:
        int data;
        SinglyLinkedListNode *next;

        SinglyLinkedListNode(int node_data) {
            this->data = node_data;
            this->next = nullptr;
        }
};

class SinglyLinkedList {
    public:
        SinglyLinkedListNode *head;
        SinglyLinkedListNode *tail;

        SinglyLinkedList() {
            this->head = nullptr;
            this->tail = nullptr;
        }

};

void print_singly_linked_list(SinglyLinkedListNode* node, string sep, ofstream& fout) {
    while (node) {
        fout << node->data;

        node = node->next;

        if (node) {
            fout << sep;
        }
    }
}

void free_singly_linked_list(SinglyLinkedListNode* node) {
    while (node) {
        SinglyLinkedListNode* temp = node;
        node = node->next;

        free(temp);
    }
}

// Complete the insertNodeAtHead function below.

/*
 * For your reference:
 *
 * SinglyLinkedListNode {
 *     int data;
 *     SinglyLinkedListNode* next;
 * };
 *
 */
***SinglyLinkedListNode* insertNodeAtHead(SinglyLinkedListNode* llist, int data) {

  SinglyLinkedListNode *nnode;
  nnode = new SinglyLinkedListNode(data);
  if(llist !=NULL)
    nnode->next=llist;
  return llist=nnode;
}***

int main()
{
    ofstream fout(getenv("OUTPUT_PATH"));

    SinglyLinkedList* llist = new SinglyLinkedList();

    int llist_count;
    cin >> llist_count;
    cin.ignore(numeric_limits<streamsize>::max(), '\n');

    for (int i = 0; i < llist_count; i++) {
        int llist_item;
        cin >> llist_item;
        cin.ignore(numeric_limits<streamsize>::max(), '\n');

        SinglyLinkedListNode* llist_head = insertNodeAtHead(llist->head, llist_item);
        llist->head = llist_head;
    }

    print_singly_linked_list(llist->head, "\n", fout);
    fout << "\n";

    free_singly_linked_list(llist->head);

    fout.close();

    return 0;
}

我只需要完成 insertNodeAtHead() 函数。休息都已经在那里了。但是,当我尝试在不使用 SinglyLinkedListNode 类类型(它们的预定义类)的指针 nnode 对象(我的标识符)的情况下执行此操作时,我得到编译错误:

#include <bits/stdc++.h>

using namespace std;

class SinglyLinkedListNode {
  public:
    int data;
  SinglyLinkedListNode * next;

  SinglyLinkedListNode(int node_data) {
    this - > data = node_data;
    this - > next = nullptr;
  }
};

class SinglyLinkedList {
  public:
    SinglyLinkedListNode * head;
    SinglyLinkedListNode * tail;

  SinglyLinkedList() {
    this - > head = nullptr;
    this - > tail = nullptr;
  }

};

void print_singly_linked_list(SinglyLinkedListNode * node, string sep, ofstream & fout) {
  while (node) {
    fout << node - > data;

    node = node - > next;

    if (node) {
      fout << sep;
    }
  }
}

void free_singly_linked_list(SinglyLinkedListNode * node) {
  while (node) {
    SinglyLinkedListNode * temp = node;
    node = node - > next;

    free(temp);
  }
}

// Complete the insertNodeAtHead function below.

/*
 * For your reference:
 *
 * SinglyLinkedListNode {
 *     int data;
 *     SinglyLinkedListNode* next;
 * };
 *
 */
***SinglyLinkedListNode * insertNodeAtHead(SinglyLinkedListNode * llist, int data) {

  SinglyLinkedListNode nnode;
  nnode = new SinglyLinkedListNode(data);
  if (llist != NULL)
    nnode.next = llist;
  return llist = & nnode;
}***

int main() {
  ofstream fout(getenv("OUTPUT_PATH"));

  SinglyLinkedList * llist = new SinglyLinkedList();

  int llist_count;
  cin >> llist_count;
  cin.ignore(numeric_limits < streamsize > ::max(), '\n');

  for (int i = 0; i < llist_count; i++) {
    int llist_item;
    cin >> llist_item;
    cin.ignore(numeric_limits < streamsize > ::max(), '\n');

    SinglyLinkedListNode * llist_head = insertNodeAtHead(llist - > head, llist_item);
    llist - > head = llist_head;
  }

  print_singly_linked_list(llist - > head, "\n", fout);
  fout << "\n";

  free_singly_linked_list(llist - > head);

  fout.close();

  return 0;
}

编译后的错误:

solution.cc:在函数'SinglyLinkedListNode * insertNodeAtHead(SinglyLinkedListNode *,int)'中:solution.cc:63:24:错误:没有匹配函数调用'SinglyLinkedListNode :: SinglyLinkedListNode()'SinglyLinkedListNode nnode; ^~~~~ solution.cc:10:9: 注意: 候选: 'SinglyLinkedListNode::SinglyLinkedListNode(int)' SinglyLinkedListNode(int node_data) { ^~~~~~~~~~~~~~~~~~ ~~ solution.cc:10:9:注意:候选人需要 1 个参数,0 提供了 solution.cc:5:7:注意:候选人:'constexpr SinglyLinkedListNode::SinglyLinkedListNode(const SinglyLinkedListNode&)' class SinglyLinkedListNode { ^~~~~ ~~~~~~~~~~~~~~~ solution.cc:5:7: note: 候选人需要 1 个参数,0 提供 solution.cc:5:7: note: Candidate: 'constexpr SinglyLinkedListNode:: SinglyLinkedListNode(SinglyLinkedListNode&&)' solution.cc:5:7: 注意:候选人需要 1 个参数,0 提供 solution.cc:64:40: 错误:'operator=' 的重载不明确(操作数类型是 'SinglyLinkedListNode' 和 'SinglyLinkedListNode* ') nnode = new SingleLinkedListNode(data); ^ solution.cc:5:7: 注意:候选:'SinglyLinkedListNode& SinglyLinkedListNode::operator=(const SinglyLinkedListNode&)' class SinglyLinkedListNode { ^~~~~~~~~~~~~~~~~~~~解决方案。 cc:5:7:注意:参数 1 的转换格式错误:solution.cc:64:11:错误:用户定义的从“SinglyLinkedListNode*”到“const SinglyLinkedListNode&”的转换无效 [-fpermissive] nnode = new单链表节点(数据);^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 解决方案.cc:10:9:
nnode = new SingleLinkedListNode(data); ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ solution.cc:64:11:错误:从'SinglyLinkedListNode*'到'int'的无效转换' [-fpermissive] solution.cc:10:34: 注意:初始化参数 1 的 'SinglyLinkedListNode::SinglyLinkedListNode(int)' SinglyLinkedListNode(int node_data) { ~~~~^~~~~~~~~ solution.cc :5:7: 注意:候选:'SinglyLinkedListNode& SinglyLinkedListNode::operator=(SinglyLinkedListNode&&)' class SinglyLinkedListNode { ^~~~~~~~~~~~~~~~~~~~ solution.cc:5:7 :注意:参数 1 的转换格式不正确:solution.cc:64:11:错误:从“SinglyLinkedListNode*”到“SinglyLinkedListNode&&”的用户定义转换无效 [-fpermissive] nnode = new SinglyLinkedListNode(data);
nnode = new SingleLinkedListNode(data); ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ solution.cc:64:11:错误:从'SinglyLinkedListNode*'到'int'的无效转换' [-fpermissive] solution.cc:10:34: 注意:初始化参数 1 的 'SinglyLinkedListNode::SinglyLinkedListNode(int)' SinglyLinkedListNode(int node_data) { ~~~~^~~~~~~~~ solution.cc :64:40:错误:从'SinglyLinkedListNode'类型的右值转换为非常量引用类型'class SinglyLinkedListNode&&' [-fpermissive] nnode = new SinglyLinkedListNode(data);

退出状态 255

我坚信它应该有效,但事实并非如此。由于逻辑相同,唯一的区别是我没有使用指针来创建对象。 由于我是 C++ 新手,我无法弄清楚为什么会发生这种情况。请给出见解。

标签: c++data-structureslinked-list

解决方案


我们可以在没有指针的情况下创建节点吗...

技术上是的,但实际上不是。在这种情况下不是。

SinglyLinkedListNode nnode;

失败是因为没有构造函数SinglyLinkedListNode不带参数。

SinglyLinkedListNode nnode(data);

或者

SinglyLinkedListNode nnode{data};

调用SinglyLinkedListNode(int node_data)并创建一个SinglyLinkedListNode,但这SinglyLinkedListNode是一个局部范围的自动变量。它会在insertNodeAtHead返回后立即销毁。这对你没用。你最终会得到一个所谓的悬空指针,一个指向死对象的指针。访问该死对象是未定义的行为。这通常是致命的,但信不信由你,当它不致命时,情况会更糟。你不知道会发生什么。通常,该程序看起来可以正常工作。然后突然之间就没有了。

您需要动态分配,而保持动态分配的最简单方法是使用指针。

边注:

return llist = nnode;

也可能是

return nnode;

这里的任务什么都不做。指针是指向对象的地址。当您将指针传递给函数时,指向的对象是通过引用传递的,但函数会获得地址的副本。llist = nnode更改地址的副本,而不是原始地址。调用函数不知道副本会发生什么,并继续使用它的原始值。

在这种情况下,你有点走运,因为

return llist = nnode;

执行无意义的赋值,然后返回 的值llist,即无论如何您想要返回的值。


推荐阅读