【问题标题】:Why function return empty object?为什么函数返回空对象?
【发布时间】:2018-02-04 22:13:15
【问题描述】:

这是 c++11。使用两个堆栈的堆栈的简单排序功能。 虽然在 sort() 函数中调试 tempStack 填充正确,但 sort() 函数返回空对象?

我试图添加 std::move() 或 std::forward() 但这是不正确的。一般 sort() 算法是正确的!此代码编译成功。 c++11的一些错误(移动语义)!

我的想法(不能正常工作!): 向前返回>(tempStack); 返回移动(tempStack);

代码(排序()):

template<typename T>
Stack<T> sort(Stack<T> &input)
{
    if(input.isEmpty()) return Stack<T>();
    Stack<T> tempStack;
    while(!input.isEmpty())
    {
        T element = input.pop();
        while(!tempStack.isEmpty() && tempStack.peek() > element) input.push(tempStack.pop());
        tempStack.push(move(element));
    }
    return tempStack;
}

代码(堆栈类):

template <typename T>
class Stack
{
public:
    Stack() : top(nullptr), stackSize(0)
    {}
    Stack(Stack &&other) : top(std::move(other.top)), stackSize(std::move(other.stackSize)) {}
    ~Stack() { while (!isEmpty()) pop(); }
    void push(T &&value)
    {
        auto n = new Node(std::forward<T>(value), top);
        top = n;
        ++stackSize;
    }
    T &peek()
    {
        if (!top) throw StackIsEmptyException();
        return top->value;
    }
    T pop()
    {
        if (!top) throw StackIsEmptyException();
        auto value(std::move(top->value));
        auto n = top;
        top = n->next;
        delete n;
        --stackSize;
        return value;
    }
    bool isEmpty() const { return !top; }
    size_t size() const { return stackSize; }
    class StackIsEmptyException
    {};
private:
    struct Node
    {
        Node(T &&v, Node *n): value(std::move(v)), next(n)
        {}
        Node(const T &v, Node *n): value(v), next(n)
        {}
        T value;
        Node *next;
    };
    Node *top;
    size_t stackSize;
};

代码(main()):

Stack<int> s;
s.push(34);;
s.push(3);
s.push(31);
s.push(98);
s.push(92);
s.push(23);

cout << sort(s).peek() << endl;

【问题讨论】:

  • 检查你的复制构造函数,它实际上并没有复制。
  • 为什么要返回move(tempStack);//调用move构造函数
  • 没有复制构造函数?
  • 除非你的移动构造函数对原始对象进行某种归零,否则它不可能知道不清理或其他任何事情。
  • 糟糕,我的意思是你的移动构造函数,是的。

标签: c++ algorithm sorting c++11 move-semantics


【解决方案1】:

当这条线运行时会发生什么?

return tempStack;
  1. tempStack 被移动到一个临时对象中。
  2. tempStack 被销毁。
  3. 返回临时对象。

在步骤 1 中,tempStacktopstackSize 被复制到临时对象(这就是您的移动构造函数所做的)。 在步骤 2 中,堆栈中的所有项目都被释放。 在第 3 步中,此返回对象的 top 现在指向已释放的内存。

您的移动构造函数应该将移动对象的 top 设置为 NULL(并且可能还将 stackSize 设置为 0),以便该对象在销毁时不会释放任何内容。

【讨论】:

    【解决方案2】:

    通知被移动的对象不应该破坏其资源是很重要的。例如,如果对象被移动,您可以使用防护装置防止清洁堆栈。

    喜欢:

    Stack(Stack &&other) : top(std::move(other.top)), stackSize(std::move(other.stackSize)) { other.moved = true; }
    
    ~Stack() { if (!moved) while (!isEmpty()) pop(); }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-08-17
      • 1970-01-01
      • 2020-12-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-09-06
      相关资源
      最近更新 更多