You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C++11双栈实现栈排序函数返回空对象问题求助

解决C++11下双栈实现栈排序返回空对象的问题

听起来你遇到的麻烦是排序后的栈在返回时变成了空对象,虽然调试时tempStack的状态完全正常,而且你尝试了std::move()和std::forward()都没解决。结合C++11的移动语义特性,我帮你排查几个最可能的原因:

1. 检查Stack类的移动构造/赋值运算符是否正确实现

如果你的Stack类自定义了析构函数、拷贝构造或拷贝赋值运算符,C++11就不会自动生成默认的移动构造函数和移动赋值运算符了。这时候你调用std::move(tempStack)其实会 fallback 到拷贝构造——如果拷贝构造是浅拷贝(比如内部用了裸指针但没做深拷贝),就会导致局部对象销毁后,返回的对象内部数据失效,看起来像空的。

正确的移动构造应该是这样的(假设Stack用std::vector存储数据):

class Stack {
private:
    std::vector<int> data;
    // 其他成员变量比如size等
public:
    // 显式默认移动构造/赋值,或者手动实现
    Stack(Stack&& other) noexcept 
        : data(std::move(other.data)) {
        // 如果有自定义的size变量,记得转移所有权:
        // this->size = other.size;
        // other.size = 0;
    }

    Stack& operator=(Stack&& other) noexcept {
        if (this != &other) {
            data = std::move(other.data);
            // 同样处理其他成员变量
        }
        return *this;
    }

    // 其他成员函数...
};

如果你的Stack类没有复杂的内部资源,直接用= default让编译器生成默认移动操作即可。

2. 移除不必要的std::move()/std::forward(),让编译器做RVO

你之前尝试的return forward<Stack>(tempStack);和return move(tempStack);可能反而帮了倒忙。C++的**返回值优化(RVO)**会自动把局部对象tempStack直接构造到函数返回的目标位置,完全不需要手动移动。手动加std::move()会把局部对象转换成右值,反而可能破坏RVO的条件——尤其是当Stack的移动构造存在bug时,问题会更明显。

正确的返回方式就是直接返回局部对象:

Stack sort(Stack input) {
    Stack tempStack;
    // ... 你的排序逻辑,填充tempStack
    return tempStack; // 让编译器自动优化
}

3. 确认排序逻辑结束后tempStack没有被意外清空

虽然你说调试时tempStack填充正常,但一定要检查return语句前的最后一行代码有没有不小心修改tempStack——比如误写了tempStack.pop()或者调用了清空函数。可以在return前加一个断点,再次确认tempStack的元素数量和内容。

4. 检查Stack的拷贝构造函数是否正确

如果移动构造没生效(比如被禁用了),函数返回时会调用拷贝构造。如果拷贝构造是浅拷贝(比如内部用裸指针但没复制数据),局部对象销毁后,返回的对象就会失去有效数据,表现为空。

比如如果Stack内部用动态数组,拷贝构造应该做深拷贝:

Stack(const Stack& other) {
    data = new int[other.capacity];
    memcpy(data, other.data, other.size * sizeof(int));
    size = other.size;
    capacity = other.capacity;
}

示例正确实现片段

这里给一个用std::vector实现的Stack和排序函数,自带正确的移动语义:

#include <vector>

class Stack {
private:
    std::vector<int> data;
public:
    Stack() = default;
    Stack(const Stack&) = default;
    Stack(Stack&&) = default;
    Stack& operator=(const Stack&) = default;
    Stack& operator=(Stack&&) = default;

    void push(int val) { data.push_back(val); }
    void pop() { if (!empty()) data.pop_back(); }
    int top() const { return data.back(); }
    bool empty() const { return data.empty(); }
    size_t size() const { return data.size(); }
};

Stack sortStack(Stack input) {
    Stack tempStack;
    while (!input.empty()) {
        int current = input.top();
        input.pop();
        // 将current插入到tempStack的正确位置
        while (!tempStack.empty() && tempStack.top() > current) {
            input.push(tempStack.top());
            tempStack.pop();
        }
        tempStack.push(current);
    }
    return tempStack;
}

内容的提问来源于stack exchange,提问作者user3455638

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.19 03:29:57