我们不能在不使用指向对象的指针的情况下创建节点C++吗?

Can't we do node creation without using pointer to object in C++?

本文关键字:情况下 指针 创建 C++ 节点 对象 不能 我们      更新时间:2023-10-16

我正在解决黑客等级链表上的这个问题: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;
}

我只需要完成插入节点AtHead()函数。其余的都已经在那里了。但是当我尝试在不使用 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 诺德; ^~~~~ solution.cc:10:9: 注意: 候选: 'SinglyLinkedListNode::SinglyLinkedListNode(int)' SinglyLinkedListNode(int node_data) { ^~~~~~~~~~~~~~~~~ 解决方案.cc:10:9: 注意:候选人需要 1 个参数,0 提供解决方案.cc:5:7: 注意: 候选人: 'constexpr SinglyLinkedListNode::SinglyLinkedListNode(const SinglyLinkedListNode&)' class SinglyLinkedListNode { ^~~~~~~~~~~~~~~~~ 解决方案.cc:5:7: 注意:候选人期望 1 个参数,0 提供解决方案.cc:5:7: 注意:候选人:"constexpr SinglyLinkedListNode::SinglyLinkedListNode(SinglyLinkedListNode&&)' 解决方案.cc:5:7:注意:候选人期望 1 个参数,提供 0 个参数 解决方案.cc:64:40:错误:"运算符="的重载不明确(操作数) 类型是 'SinglyLinkedListNode' 和 'SinglyLinkedListNode*') nnode = new SinglyLinkedListNode(data); ^ solution.cc:5:7: 注意:候选人:'SinglyLinkedListNode& SinglyLinkedListNode::operator=(const SinglyLinkedListNode&)' class SinglyLinkedListNode { ^~~~~~~~~~~~~~~~~~ 解决方案.cc:5:7: 注意:参数 1 的转换格式不正确: 解决方案.cc:64:11: 错误: 无效 用户定义的从"SinglyLinkedListNode*"到"const SinglyLinkedListNode&' [-fpermissive] nnode = new SinglyLinkedListNode(data); ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 解决方案.cc:10:9: 注意:候选者是:"SinglyLinkedListNode::SinglyLinkedListNode(int)" SinglyLinkedListNode(int node_data) { ^~~~~~~~~~~~~~~~~~ 解决方案.cc:10:9: 注意:参数 1 的转换格式不正确: 解决方案.cc:64:11: 错误: 无效 从 'SinglyLinkedListNode*' 到 'int' [-fpermissive]
nnode = new SinglyLinkedListNode(data); ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ [-fallowive] solution.cc:10:34:注意:初始化参数 1 的 'SinglyLinkedListNode::SinglyLinkedListNode(int)' SinglyLinkedListNode(int node_data) { ~~~~~^~~~~~~~ 解决方案.cc:5:7: 注意:候选者:'SinglyLinkedListNode& SinglyLinkedListNode::operator=(SinglyLinkedListNode&&)' 类 SinglyLinkedListNode { ^~~~~~~~~~~~~~~~~~ 解决方案.cc:5:7: 注意:参数 1 的转换格式不正确: 解决方案.cc:64:11: 错误: 无效 用户定义的从"SinglyLinkedListNode*"到"的转换 'SinglyLinkedListNode&&' [-fpermissive] nnode = new SinglyLinkedListNode(data); ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 解决方案.cc:10:9: 注意:候选者是:"SinglyLinkedListNode::SinglyLinkedListNode(int)" SinglyLinkedListNode(int node_data) { ^~~~~~~~~~~~~~~~~~ 解决方案.cc:10:9: 注意:参数 1 的转换格式不正确: 解决方案.cc:64:11: 错误: 无效 从 'SinglyLinkedListNode*' 到 'int' [-fpermissive]
nnode = new SinglyLinkedListNode(data); ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ [-fallowive] solution.cc:10:34:注意:初始化参数 1 的 'SinglyLinkedListNode::SinglyLinkedListNode(int)' SinglyLinkedListNode(int node_data) { ~~~~^~~~~~~~~ 解决方案.cc:64:40:错误:转换为非常量引用类型"类 SinglyLinkedListNode&&" 从类型为"SinglyLinkedListNode"的右值 [-fpermissive] nnode = new SinglyLinkedListNode(data);

退出状态 255

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

作为参考,下面是您修改的代码段,您认为它是问题的根源:

工作代码

SinglyLinkedListNode *nnode;
nnode = new SinglyLinkedListNode(data);

损坏的代码

SinglyLinkedListNode nnode;
nnode = new SinglyLinkedListNode(data);

静态对象与动态对象

正如您所说,不同之处在于nnode在工作版本中是 Node 指针对象,而在您的版本中,它是一个 Node 对象。问题在于使用new关键字(请参阅此处)。

[new关键字] 创建和初始化具有动态存储持续时间的对象,即其生存期不受创建范围限制的对象。

您正在尝试使用动态内存创建静态对象。它不行。您可以将其创建为静态对象,只需说:

SinglyLinkedListNode nnode(data);

(见这里)更深入地解释实例化(创建实例)类对象。

错误信息

error: no matching function for call to ‘SinglyLinkedListNode::SinglyLinkedListNode()’ SinglyLinkedListNode nnode; ^~~~~ solution.cc:10:9: note: candidate: ‘SinglyLinkedListNode::SinglyLinkedListNode(int)’ SinglyLinkedListNode(int node_data) { ^~~~~~~~~~~~~~~~~~~~ solution.cc:10:9: note: candidate expects 1 argument, 0 provided 

根据您的错误消息,它似乎更多地存在于构造函数的问题中。

它似乎无法为您的 SinglyLinkedListNode 类找到默认构造函数。其中,您尝试调用该函数。我的猜测是,它将非指针 ListNode 的实例化视为该类的默认构造函数,而您没有该类。这个人也有同样的问题。

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

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

SinglyLinkedListNode nnode;

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

SinglyLinkedListNode nnode(data);

SinglyLinkedListNode nnode{data};

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

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

旁注:

return llist = nnode;

不妨是

return nnode;

此处的作业不执行任何操作。指针是指向对象的地址。将指针传递到函数中时,指向的对象通过引用传递,但函数会获取地址的副本。llist = nnode更改地址的副本,而不是原始地址。调用函数不知道副本会发生什么,并继续使用它的原始值。

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

return llist = nnode;

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

SinglyLinkedListNode *nnode; nnode = new SinglyLinkedListNode(data);

new 返回一个指针。 此指针包含对象的地址,这意味着它指向对象(用一般语言)。

SinglyLinkedListNode nnode; nnode = new SinglyLinkedListNode(data);

这里 nnode 已经是一个对象,您正在尝试为其分配指针类型。

class_type和class_type*是不同的。 任何类型的代码的每个指针都是 4 字节或 8 字节,因为它是一个地址。 所以不要与对象和对象指针混淆。

相关文章: