使用指针成员变量重载类中的+运算符

时间:2013-10-12 08:06:36

标签: c++ pointers operator-overloading

我有一个非常简单的课程。它有一个指针成员变量。我想重载+运算符。但是,它不起作用!这是我的代码:

#include <iostream>
using namespace std;


template <typename T> 
struct Node{
    Node *next;
    T data;
};

template <typename T> 
class stack{
protected:
    Node <T> *head;

public:
    stack();
    ~stack();
    bool push(T);
    stack <T> operator+ (stack <T>);

};

template <typename T> 
stack<T>::stack(){
    head = NULL;
}

template <typename T>  
stack <T>::~stack(){
    Node <T> *temp;

    while(head){
        temp = head;
        head = head->next;
        delete temp;
    }
}

template <typename T> 
bool stack <T>::push(T data){
    Node <T> *newElem = new Node <T>;
    if (!newElem) return false;

    newElem->next = head;
    newElem->data = data;
    head = newElem;
    return true;
}

template <typename T> 
stack <T> stack<T>::operator+ (stack <T> stack1){
    stack <T> result;
    Node <T> *temp = head;

    while (temp) {
        result.push(temp->data);
        temp = temp->next;
    }

    temp = stack1.head;
    while (temp) {
        result.push(temp->data);
        temp = temp->next;
    }

    return result;
}

int main(){
    stack <int> myStack1, myStack2, myStack3;

    myStack1.push (1);
    myStack1.push (2);

    myStack2.push (3);
    myStack2.push (4);

    myStack3 = myStack1 + myStack2; //  here at runtime myStack3 is not the result of myStack1 + myStack2. 
    return 0;
}
你可以帮我解决这个问题吗? 请注意,这仅适用于练习。

非常感谢。

2 个答案:

答案 0 :(得分:2)

您在类声明中声明了其他内容,您在定义中写了+=而不是+

stack <T> operator+ (stack <T>);
                  ^

stack <T> stack<T>::operator+= (stack <T> stack1){
                            ^^

答案 1 :(得分:2)

您的问题是您正在创建运营商右侧的副本。签名应该是:

template <typename T> 
stack <T> stack<T>::operator+ (const stack <T>& stack1) { ... }

因此您只引用stack1,而不是复制它。

这将解决您遇到的直接问题,但从长远来看,您还希望实现正确的复制构造函数,因为stack的所有副本当前都会损坏内存链接相同的元素,destrutor将删除它们,另一个stack然后引用已删除的元素

这就是为什么您看到“结果”具有预期值的原因,名为stack1的副本尚未删除。但是当operator+返回时,它会删除stack1,因此会删除stack1的所有元素。并非所有复制到引用stack1中元素的结果的指针都无效。这就是呼叫后stack3出现故障的原因。

另请参阅rule of three,阅读答案中的“管理资源”部分。


更新:这还不够,因为您还分配了operator+的结果,再次适用三条规则,因为您也没有正确的赋值运算符。您可能希望将这些添加到您的班级:

template <typename T> 
stack<T>::stack(const stack<T>& src)
{
    // this will reverse the src, I'll leave it to you to fix the order!
    head = NULL;
    Node<T>* tmp = src->head;
    while( tmp ) {
        push( tmp->data );
        tmp = tmp->next;
    }
}

template <typename T> 
stack<T>& stack<T>::operator=( stack<T> src ) // copy the argument is OK here!
{
    stack old;
    old->head = head;
    head = src->head;
    src->head = NULL;
}

由于您正在学习,以上是一个很好的起点。你现在必须

  • 反转元素顺序
  • 的方式实现复制构造函数
  • 了解赋值运算符的工作原理。我使用了一个不寻常的实现,但是一旦你理解了它,你就学到了很多关于对象的生命周期:)