【问题标题】:C++ - Linked List Stack Operator Overloading FunctionC++ - 链表栈运算符重载函数
【发布时间】:2011-05-03 05:36:27
【问题描述】:

我目前正在研究实现链表的堆栈。在重载“=”运算符时遇到问题。我不知道该怎么做。如果有人能指出一个好的方向,那就太棒了。

//operator overload
template <class S>
const Stack<S>::operator=( const Stack& s )
{

    if (s.isEmpty())
        theFront = theTop = 0
    else
    {
        NodePointer temp = q->theFront;

        while(temp != 0)
        {
            push(temp->data);
            temp = temp->next;
        }
    }

    return *this;
}

我也收到此错误: 堆栈,std::allocator > >::Node::Node(std::basic_string, std::allocator >)' 引用自 C:\USERS\JOHNNY\DESKTOP\STACK\INFIX_TO_RPN.OBJ

我的操作符重载函数可以解决这个问题吗?

【问题讨论】:

    标签: c++ operator-overloading stack linked-list


    【解决方案1】:

    您需要先清空当前堆栈,然后再向其推送数据。您应该添加一个 removeAll 函数,并在分配的顶部调用它(在检查自分配之后,这也是一个好主意)。否则,它看起来是正确的。所以,最终的结果是:

    //operator overload 
    template <class S> 
    const Stack<S>::operator=( const Stack& s ) 
    { 
        // Check for self assignment
        if (&s==this)
            return *this;
    
        // Clear the current stack
        removeAll();
    
        // Copy all data from stack s
        if (!s.isEmpty())
        { 
            NodePointer temp = q->theFront; 
    
            while(temp != 0) 
            { 
                push(temp->data); 
                temp = temp->next; 
            } 
        } 
    
        return *this; 
    } 
    

    这里是一个示例 removeAll 函数:

    template <class S> 
    void Stack<S>::removeAll()    
    { 
        while (s.theFront)
        {
            NodePointer p = s.theFront;
    
            s.theFront = s.theFront->next;
            delete p;
        }
    
        s.theTop = s.theFront;
    }
    

    【讨论】:

    • 你知道为什么我会得到这个错误吗?堆栈<:basic_string std::char_traits>, std::allocator >::Node::Node(std::basic_string, std: :allocator >)' 引用自 C:\USERS\JOHNNY\DESKTOP\STACK\INFIX_TO_RPN.OBJ
    • 我认为这是链接时间错误,因为节点构造函数未定义(或不​​是构建的一部分)?
    • 我的节点类是我的堆栈类的私有成员。
    • 但是,Node 构造函数有定义吗?该定义(即,如果它在 .cpp 文件中)是您的构建(即链接)的一部分吗?
    • 是的,它是我构建的一部分。它已被定义。
    【解决方案2】:

    不要为您的班级手动实现复制赋值运算符,而是使用the copy-and-swap idiom

    一旦你为你的类实现了swap() 函数(我在上面链接的那篇文章很好地描述了如何做到这一点),operator= 重载就变得简短而简单:

    Stack& operator=(Stack rhs)
    {
        swap(rhs);
        return *this;
    }
    

    【讨论】:

    • 您确实意识到,通过按值传递 rhs,您将在每次赋值时深度复制右侧,即使这里有可能获得异常安全性?
    • @Michael:你必须复制一份。您可以选择通过值获取 rhs 并在函数调用中制作副本,或者通过 const 引用获取 rhs 并在赋值运算符的主体中自己制作副本。编译器可能经常能够消除以前的副本;这一切,但肯定不能忽略后者。
    • 考虑如果源堆栈和目标堆栈都非常大会发生什么(提示:3 > 2)
    • @Michael:我已经考虑过了。你读过我链接的文章吗?
    • 这不是一篇文章,它是一个指向 SO 问题的指针,其中的链接太小(无法人工阅读),答案太多而无法“掩盖”。正是在这一点上,我完全失去了兴趣。
    猜你喜欢
    • 2016-07-21
    • 2012-03-23
    • 1970-01-01
    • 2011-12-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多