繁体   English   中英

用C ++中的链表实现堆栈,复制构造函数

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

我正在尝试使用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的copy-constructor创建m_stack

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

您创建一个名为m_stack的局部变量。 这将屏蔽成员变量m_stack 您需要删除LinkedList

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

此外,您还需要复制成员的副本分配运算符( operator= )。 您定义了一个复制构造函数,因此需要考虑c ++的“ Rule of Three”

您要实现的内容已经是该语言的一部分:

#include <stack>
#include <list>

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

如果您这样做是为了学习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-initialiser-list:

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

这将调用LinkedList的副本构造函数,而不是赋值运算符。

尽管如此,任何管理资源的类(实际上是任何C ++类)都必须遵循“三个规则”才能正常工作。 该规则指出,如果类具有自定义副本构造函数,自定义副本赋值运算符或自定义析构函数,则应定义所有这三个类以使其正常工作。 LinkedList有一个复制构造函数和一个析构函数,这意味着您还应该提供一个复制赋值运算符,例如:

LinkedList& operator= (const LinkedList &src);

我将把它的实现留给读者练习;-)您还可以查找“复制和交换”惯用语。

完成此操作后,您实际上应该从Stack 删除复制构造函数(可能还包括析构函数),因为默认生成的副本构造函数将满足您的需要-在每个成员上调用复制构造函数。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM