首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >在C++中使用链表实现堆栈,复制构造函数

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

Stack Overflow用户
提问于 2014-05-01 09:29:49
回答 4查看 1.1K关注 0票数 1

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

我正在使用以下类:

代码语言:javascript
运行
复制
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()等等),我无法获得当前堆栈的副本。

我确实试着写了以下几点:

代码语言:javascript
运行
复制
Stack::Stack(const Stack &copyStack){
    LinkedList m_stack = copyStack.m_stack;
}

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

我是C++的新手,我想我在那里漏掉了什么。

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2014-05-01 09:41:23

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

要学习这门语言,你应该先学会使用这些语言,然后再深入研究如何实现这些语言。

另一方面,如果您这样做是为了了解数据结构和内存管理( C++只是这方面的一个工具),那就继续吧。但是,如果在你投入到这样低水平的任务之前,你会更好地了解语言。

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

代码语言:javascript
运行
复制
Stack::Stack(const Stack &copyStack){
    m_stack = copyStack.m_stack;
}

其次,这需要LinkedList实现一个适当的副本赋值操作符。如果没有这一点,将使用默认生成的一个,它只复制所有成员。这只会导致一个浅表副本--新构造的堆栈对象和原始的copyStack都会指向它们的LinkedList中的相同节点--可能不是您想要的。

不过,更好的方法是使用适当的值初始化m_stack;您现在所做的是将m_stack初始化为空,然后对其进行分析。应将复制构造函数更改为使用成员初始化-列表:

代码语言:javascript
运行
复制
Stack::Stack(const Stack &copyStack) : m_stack(copyStack.m_stack)
{}

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

不过,任何管理资源的类(实际上是任何C++类)都必须遵循"Rule of Three"才能正确工作。该规则规定,如果类具有自定义副本构造函数、自定义副本赋值运算符或自定义析构函数,则应定义所有3种类型才能正确工作。LinkedList有一个副本构造函数和一个析构函数,这意味着您还应该提供一个副本赋值操作符,例如:

代码语言:javascript
运行
复制
LinkedList& operator= (const LinkedList &src);

我将把它的实现作为读者的摘录;-)您也可以查找“复制和交换”成语。

一旦这样做,您实际上应该从Stack中移除复制构造函数(可能也包括析构函数),因为默认生成的构造函数将完成您需要的任务--在每个成员上调用复制构造函数。

票数 0
EN

Stack Overflow用户

发布于 2014-05-01 09:47:41

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

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

代码语言:javascript
运行
复制
Stack(const Stack& copyStack) : m_stack(copyStack.m_stack) {}

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

当然,这取决于这样一个事实:您必须正确地实现了LinkedList(const LinkedList& obj);

票数 2
EN

Stack Overflow用户

发布于 2014-05-01 09:32:41

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

代码语言:javascript
运行
复制
Stack::Stack(const Stack &copyStack){
    m_stack = copyStack.m_stack;
}

此外,还需要一个复制赋值操作符(operator=)来复制成员。您定义了一个副本构造函数,因此您需要考虑c++的“三条规则”

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/23405152

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档