我正在尝试使用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 ++的新手,我想我错过了一些东西..
答案 0 :(得分:2)
编译器生成的拷贝构造函数可以工作。
如果你真的想手动实现它,那么:
Stack(const Stack& copyStack) : m_stack(copyStack.m_stack) {}
请注意,您应该使用构造函数初始化列表。然后使用m_stack
的复制构造函数创建LinkedList
。
当然,这取决于您必须正确实施LinkedList(const LinkedList& obj);
的事实!
答案 1 :(得分:0)
您创建一个名为m_stack
的局部变量。这会掩盖成员变量m_stack
。您需要删除LinkedList
:
Stack::Stack(const Stack ©Stack){
m_stack = copyStack.m_stack;
}
您还需要一个复制成员的复制赋值运算符(operator=
)。您定义了一个复制构造函数,因此您需要考虑"三个规则"对于c ++
答案 2 :(得分:0)
您尝试实施的内容已经成为该语言的一部分:
#include <stack>
#include <list>
int main()
{
std::stack<int, std::list<int>> my_stack;
}
答案 3 :(得分:0)
如果您正在这样做以学习C ++,因为您应该将其用于正常编程,请考虑采用不同的路径(例如尝试创建一个简单的程序,而不是数据结构)。这是因为C ++已经为你在这里使用的大多数事情都有标准的库实现,比如指针自动管理内存释放(std::unique_ptr
),链表(std::forward_list
和{ {1}}),甚至是一个堆栈(std::list
)。
要了解这门语言,您应该先学习如何使用这些语言,然后再深入了解如何实施这些语言。
另一方面,如果您正在这样做以了解数据结构和内存管理(并且C ++只是这方面的工具),请继续。但是,如果你在深入了解这些低级别的任务之前更了解语言,那么你会变得更好。
然而,您的代码中存在两个问题。一种是声明一个新的局部变量而不是分配给一个成员。你可能意味着这个:
std::stack
其次,这需要Stack::Stack(const Stack ©Stack){
m_stack = copyStack.m_stack;
}
来实现适当的复制赋值运算符。如果没有这个,将使用默认生成的一个,它只复制所有成员。这只会导致浅拷贝 - 新构建的堆栈对象和原始LinkedList
都指向copyStack
内的相同节点 - 可能不是你想要的。
但是,更好的方法是使用适当的值初始化 LinkedList
;您现在正在做的事情是将m_stack
初始化为空,然后进行分配。您应该更改复制构造函数以使用member-initialiser-list:
m_stack
这将调用Stack::Stack(const Stack ©Stack) : m_stack(copyStack.m_stack)
{}
的复制构造函数,而不是赋值运算符。
但是,任何管理资源的类(实际上是任何C ++类)都必须遵循"Rule of Three"才能正常工作。该规则规定,如果一个类具有自定义拷贝构造函数,自定义拷贝赋值运算符或自定义析构函数,它应该定义所有这三个正确工作。 LinkedList
有一个复制构造函数和一个析构函数,这意味着你还应该提供一个复制赋值运算符,例如像这样:
LinkedList
我将把它的实现作为读者的练习;-)你也可以查找&#34;复制和交换&#34;成语。
一旦你这样做,你实际上应该从LinkedList& operator= (const LinkedList &src);
删除复制构造函数(也可能是析构函数),因为默认生成的复制构造函数将完成你所需要的 - 调用复制每个成员的构造函数。