在c++中使用链表实现堆栈,复制构造函数

implementing stack with a linked list in C++ , copy constructor

本文关键字:堆栈 复制 构造函数 实现 链表 c++      更新时间:2023-10-16

我正在尝试在c++中使用链表实现堆栈,我不知道如何正确编写堆栈类的复制构造函数。

我使用以下类:

class Node{
    int m_num;
    Node* m_pNext;
public:
    Node();
    ~Node();
    //and the standard get&set functions..
}

class LinkedList{
    int m_size;
    Node* m_pHead;
public:
    LinkedList();
    LinkedList(const LinkedList& obj);
    ~LinkedList();
    //and the standard get&set functions..
}

class Stack{
    LinkedList m_stack;
public:
    Stack();
    Stack(const Stack& copyStack);
    ~Stack();
}
我确实写了LinkedList类的复制构造函数,它运行得很好。我的问题是Stack类,在那里我不能得到我当前堆栈的副本,以便在堆栈中搜索(涉及pop()等)。

我确实试着写了以下内容:

Stack::Stack(const Stack &copyStack){
    LinkedList m_stack = copyStack.m_stack;
}

就像我说的,它不起作用。

我是c++的新手,我想我在那里错过了一些东西。

编译器生成的复制构造函数可以工作。

如果你真的想手动实现它,那么:

Stack(const Stack& copyStack) : m_stack(copyStack.m_stack) {}

注意,你应该使用构造函数初始化列表。然后使用LinkedList的复制构造函数创建m_stack

当然,这依赖于您必须正确实现LinkedList(const LinkedList& obj);的事实!

如果你这样做是为了学习c++,因为你应该使用它进行正常编程,请考虑采取不同的路线(例如尝试创建一个简单的程序,而不是数据结构)。这是因为c++已经为您在这里使用的大多数东西提供了标准库实现,例如指针自动管理内存释放(std::unique_ptr),链表(std::forward_liststd::list),甚至堆栈(std::stack)。

要学习这门语言,在你深入研究如何实现它们之前,你应该先学习如何使用它们。


另一方面,如果您这样做是为了学习数据结构和内存管理(c++只是这方面的一个工具),请继续。但是,如果你在深入研究这种低级任务之前对语言有更好的了解,那就更好了。

然而,在你的代码中有两个问题。一种是声明一个新的局部变量,而不是给成员赋值。你的意思可能是:

Stack::Stack(const Stack &copyStack){
    m_stack = copyStack.m_stack;
}

第二,这要求LinkedList实现一个合适的拷贝赋值操作符。否则,将使用默认生成的一个,它只是复制所有成员。这将导致只进行浅拷贝——新构建的堆栈对象和原始copyStack都指向它们的LinkedList内部的相同节点——可能不是您想要的。

然而,一个更好的方法是用适当的值初始化 m_stack;你现在所做的是将m_stack初始化为空,然后赋值给它。您应该更改复制构造函数以使用member- initializer -list:
Stack::Stack(const Stack &copyStack) : m_stack(copyStack.m_stack)
{}

这将调用LinkedList的复制构造函数,而不是赋值操作符。

然而,任何管理资源的类(实际上是任何c++类)都必须遵循"三法则"才能正常工作。该规则规定,如果一个类有自定义复制构造函数、自定义复制赋值操作符或自定义析构函数,它应该定义所有这三个才能正常工作。LinkedList有一个复制构造函数和一个析构函数,这意味着你还应该提供一个复制赋值操作符,例如:

LinkedList& operator= (const LinkedList &src);

我将把它的实现留给读者作为练习;-)您也可以查找"复制和交换"习语。

这样做之后,实际上应该Stack中删除复制构造函数(也可能是析构函数),因为默认生成的复制构造函数将满足您的需要——在每个成员上调用复制构造函数。

你想要实现的东西已经是语言的一部分了:

#include <stack>
#include <list>
int main()
{
    std::stack<int, std::list<int>> my_stack;
}

创建一个名为m_stack的局部变量。这掩盖了成员变量m_stack。您需要删除LinkedList:

Stack::Stack(const Stack &copyStack){
    m_stack = copyStack.m_stack;
}

还需要复制赋值操作符(operator=)来复制成员。您定义了一个复制构造函数,因此您需要考虑c++

的"三规则"