因此,我尝试使用链接列表和类来实现堆栈。现在,我有6个不同的文件:node.h,node.cpp,LL.h,LL.cpp,Stack.h和Stack.cpp。我想完成Stack.h和Stack.cpp文件,以便它们可以正常工作。我已经实现了链表功能,它们可以正常工作。这是代码:
node.h:
// node.h
class node { // node class used in the LL (linked list) class
private:
node * next; // Pointer to next node of an LL
int data; // integer data stored in this node
public:
node(int x, node * n); // Constructor
~node(); // Destructor
void set_data(int x); // Change the data of this node
void set_next(node * n);// Change the next pointer of this node
int get_data(); // Access the data of this node
node * get_next(); // Access the next pointer of this node
};
LL.h:
// LL.h
#include "node.h"
// Linked list class, used in the Stack class
class LL {
private:
node * head; // pointer to first node
node * tail; // pointer to last node
public:
LL(); // Constructor
~LL(); // Destructor
void prepend(int value); // add a node to the beginning of the LL
int removeHead(); // remove the first node of the LL
void print(); // print the elements of the LL
node * get_head(); // access the pointer to the first node of the LL
};
Stack.h:
// Stack.h
#include "LL.h"
class Stack {
private:
LL_t intlist;
public:
Stack(); // Constructor
~Stack(); // Destructor
void push(int value);
int pop();
int isEmpty();
void print();
};
最后, Stack.cpp:
// Stack.cpp
#include "Stack.h"
#include <stdio.h>
Stack::Stack() {
head= NULL;
tail= NULL;
}
Stack::~Stack() {
delete intlist;
}
int Stack::isEmpty() {
return (head==NULL);
}
void Stack::push(int value) {
head= value;
}
int Stack::pop() {
if ( !isEmpty() ) {
int temp= tail->get_data();
delete tail;
return temp;
}
return -1;
}
我遇到了编译问题。它说get_data()是未定义的,而“ head”和“ tail”是未定义的,即使我在Stack.h和LL.h中有“ #include“ LL.h”“,我也有” #include“ node.h ”,因此它们都相互依赖,因此应该正确工作吗?我希望它可以编译,以便可以查看我是否正确实现了Stack.h和Stack.cpp。您看到我的实施方式有任何问题吗?如果是这样,您能指出他们吗?此外,关于我为什么遇到这些编译问题的任何想法?任何帮助表示赞赏!
答案 0 :(得分:0)
让我们看看您的实际问题
Stack::Stack() {
head= NULL;
tail= NULL;
}
导致错误"head" and "tail" is undefined
。现在看一下头文件,head
和tail
的声明在哪里?答案是在LL
类中,而不是Stack
类中。 LL
类负责初始化head
类的默认构造函数中的tail
和LL
。因此,您的Stack
构造函数应该看起来像这样
Stack::Stack() {
}
只要您有一个包含另一个类的类的构造函数,就会调用另一个类的构造函数。在Stack
的情况下,LL
的默认构造函数被隐式调用,这将为您初始化head
和tail
。您无需执行任何操作。
现在让我们看一下更多的实现。
Stack::~Stack() {
delete intlist;
}
intList
不是指针,因此无法删除。显然,您正在尝试“调用”列表的析构函数,但就像构造函数一样,这是自动发生的。您的析构函数应如下所示:
Stack::~Stack() {
}
或者您可以(可能应该)将其完全删除。
继续前进
int Stack::isEmpty() {
return (head==NULL);
}
再次尝试在无法访问的地方访问head
。您的Stack
类有一个LL intlist
对象,因此应该使用它,例如(
int Stack::isEmpty() {
return intlist.get_head() == NULL;
}
这里有东西
void Stack::push(int value) {
head= value;
}
应该是
void Stack::push(int value) {
intlist.prepend(value);
}
使用堆栈具有的对象(intlist
)而不是其他对象的内部对象。
我会让你把剩下的都整理一下。但是您必须了解班级设计中存在的责任划分。 Stack
类不应(也不能)与LL
类的内部有关。 Stack
需要执行的所有操作都应该可以通过LL
类的公共接口来完成。如果不是,则需要更改LL
类。
还要注意,您的pop
实现不仅在执行上是错误的,而且在概念上也是错误的。 Pop
应该删除列表的头,而不是尾巴。堆栈是LIFO列表(后进先出),因此pop
会删除最近添加的项目。现在查看LL
类,有一个removeHead
方法(提示,提示)。