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

overloading the + operator in a class with a pointer member variable

本文关键字:运算符 重载 指针 成员 变量      更新时间:2023-10-16

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

#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;
}

你能帮我这个吗?请注意,这只是为了练习。

谢谢。

您的问题是您正在创建运算符右侧的副本。签名应为:

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

这样你只是引用stack1,而不是复制它。

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

这就是为什么您看到"结果"具有预期值,名为stack1的副本尚未被删除。但是当operator+返回时,它会删除stack1,因此stack1的所有元素都将被删除。并非所有复制到结果的引用stack1元素的指针都是无效的。这就是为什么stack3在通话后看起来坏了。

另请参阅三法则,请阅读答案中的"管理资源"部分。


更新:这还不够,因为您还分配了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;
}

既然你正在学习,以上这是一个很好的起点。你现在必须

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

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

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