【发布时间】:2019-05-02 06:58:21
【问题描述】:
我不明白当我重载运算符 + 时出了什么问题 (这样做的目的是将 2 个堆栈合并为一个新堆栈)... 它返回“总和”,但会更改先前的值。 ///////////////////////////////////////// ///////////////////////////////////////// ///////////////////////////////////////// /////////////
template <typename T>
classStack
{
private:
struct Node
{
T data;
Node *next;
} *top;
std::size_t size;
public:
Stack();
~Stack();
void push(T data);
void pop(void);
size_t get_size(void);
const Stack& operator=(const Stack &stack_obj);
const Stack operator+(const Stack &stack_obj);
void show_all_stack(void);
};
template <typename T>
const Stack<T> Stack<T>::operator+(const Stack &stack_obj)
{
Stack stack;
Node *tmp;
if (!this->size && !stack_obj.size) {
return stack;
}
if (!stack_obj.size)
{
stack.size = size;
stack.top = top;
}
else if (!size)
{
stack.size = stack_obj.size;
stack.top = stack_obj.top;
}
else
{
stack.size = size + stack_obj.size;
stack.top = new Node;
stack.top = top;
tmp = stack.top;
while (tmp->next)
tmp = tmp->next;
tmp->next = new Node;
tmp->next = stack_obj.top;
}
return stack;
}
默认构造函数
template <typename T>
Stack<T>::Stack(void): top(nullptr), size(0)
{
}
析构函数
template <typename T>
Stack<T>::~Stack(void)
{
Node *next;
if (!size)
std::cout << "Stack is empty!\n";
else
{
while (top != nullptr)
{
next = top->next;
delete top;
top = next;
}
top = nullptr;
}
}
赋值运算符
template <typename T>
const Stack<T>& Stack<T>::operator=(const Stack<T> &stack_obj)
{
Node *tmp;
Node *ptr;
Node *last;
Node *new_node;
if (&stack_obj != this)
{
while (top != nullptr)
{
tmp = top;
top = top->next;
delete tmp;
}
top = nullptr;
size = stack_obj.size;
ptr = stack_obj.top;
while (ptr)
{
new_node = new Node;
new_node->data = ptr->data;
new_node->next = nullptr;
if (!top)
{
top = new_node;
last = new_node;
}
else
{
last->next = new_node;
last = new_node;
}
ptr = ptr->next;
}
}
}
【问题讨论】:
-
我们需要知道
Stack<T>的复制语义(复制构造函数、赋值操作符和析构函数)。底线是,如果Stack<T>具有不正确或错误的复制语义,则按值返回Stack<T>也是错误的。此外,除非复制语义正确,否则不应实现按值返回Stack<T>的函数(例如您的operator +)。 -
stack.top = top;刚刚将this拥有的指针分配给另一个对象。现在两个对象都引用相同的节点。您需要从this和stack_obj复制节点并将副本插入stack。旁注:stack.top = new Node;后跟stack.top = top;是泄漏。新的Node丢失了。您想创建新的Nodes,但又不想覆盖指向它们的唯一指针。 -
有关@Paul 警告的错误的更多信息,请阅读What is The Rule of Three?,然后阅读其朋友Rules of Five and Zero. 您的目标应该是保持资源拥有类符合三或五规则这些课程的用户可以遵守零规则并尽可能保持无知。
-
没有复制构造函数?如果没有,那么你就有麻烦了——
operator +并且任何返回Stack<T>的函数都被破坏了。其次,当您的赋值运算符必须返回一个值时,它不会返回一个值(您声明它返回一个Stack<T>&)。第三,将该代码移出赋值运算符,并实现一个复制构造函数。然后一旦你有了复制构造函数和析构函数正常工作,赋值运算符变得非常简单。所以总的来说,你的问题与operator +没有直接关系——你复制的基础被破坏了(正如我在第一条评论中提到的那样)。
标签: c++ templates stack operator-overloading