[英]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 ©Stack){
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 ©Stack){
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_list
和std::list
),甚至是堆栈( std::stack
)。
要学习该语言,您应该先学习使用这些语言,然后再深入研究如何实现它们。
另一方面,如果您正在这样做以了解数据结构和内存管理(C ++只是这方面的工具),请继续。 但是,如果您在进行此类低级任务之前对语言有更好的了解,就会更好。
但是,您的代码中有两个问题。 一种是您声明一个新的局部变量,而不是分配给成员。 您可能的意思是:
Stack::Stack(const Stack ©Stack){
m_stack = copyStack.m_stack;
}
其次,这要求LinkedList
实现适当的副本分配运算符。 否则,将使用默认生成的成员,它仅复制所有成员。 这只会导致浅表副本-新建的堆栈对象和原始copyStack
都将指向其LinkedList
的相同节点-可能不是您想要的。
不过,执行此操作的更好方法是使用适当的值初始化 m_stack
。 现在,您正在执行的操作m_stack
初始化为空,然后将其初始化。 您应该将复制构造函数更改为使用member-initialiser-list:
Stack::Stack(const Stack ©Stack) : m_stack(copyStack.m_stack)
{}
这将调用LinkedList
的副本构造函数,而不是赋值运算符。
尽管如此,任何管理资源的类(实际上是任何C ++类)都必须遵循“三个规则”才能正常工作。 该规则指出,如果类具有自定义副本构造函数,自定义副本赋值运算符或自定义析构函数,则应定义所有这三个类以使其正常工作。 LinkedList
有一个复制构造函数和一个析构函数,这意味着您还应该提供一个复制赋值运算符,例如:
LinkedList& operator= (const LinkedList &src);
我将把它的实现留给读者练习;-)您还可以查找“复制和交换”惯用语。
完成此操作后,您实际上应该从Stack
删除复制构造函数(可能还包括析构函数),因为默认生成的副本构造函数将满足您的需要-在每个成员上调用复制构造函数。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.