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

如何将现有C++链式栈代码修改为完全使用智能指针实现

C++ 链式栈智能指针改造实现

核心改造规则

  • 所有内存管理替换为std::unique_ptr,完全消除new、delete操作与持有所有权的原始指针声明
  • 移除冗余析构函数:智能指针自动管理资源生命周期,无需手动销毁节点
  • 尽可能使用auto推导类型,减少冗余类型声明
  • 保留原接口所有功能、异常逻辑与性能表现

完整改造后代码

#include <memory>
#include <string>
#include <utility>
#include "PrecondViolatedExcep.h"

template<typename ItemType>
class Node {
private:
    ItemType item;
    std::unique_ptr<Node<ItemType>> next;
public:
    Node(const ItemType& val) : item(val) {}
    Node(const ItemType& val, std::unique_ptr<Node<ItemType>> nextPtr) 
        : item(val), next(std::move(nextPtr)) {}
    
    ItemType getItem() const { return item; }
    const std::unique_ptr<Node<ItemType>>& getNext() const { return next; }
    void setNext(std::unique_ptr<Node<ItemType>> nextPtr) { next = std::move(nextPtr); }
};

template<typename ItemType>
class LinkedStack {
private:
    std::unique_ptr<Node<ItemType>> topPtr;
public:
    LinkedStack() = default;
    LinkedStack(const LinkedStack<ItemType>& aStack);
    // 移动构造默认生成即可,无需手动实现
    LinkedStack(LinkedStack<ItemType>&&) = default;
    LinkedStack& operator=(LinkedStack<ItemType>) = default; // 复制交换惯用法

    bool isEmpty() const;
    bool push(const ItemType& newItem);
    bool pop();
    ItemType peek() const;
};

// 以下为对应成员函数改造实现
template <typename ItemType>
LinkedStack<ItemType>::LinkedStack(const LinkedStack<ItemType>& aStack) {
    if (!aStack.topPtr) {
        return;
    }
    // 仅使用临时观察指针遍历,不持有所有权
    auto origStackPtr = aStack.topPtr.get();
    try {
        topPtr = std::make_unique<Node<ItemType>>(origStackPtr->getItem());
        auto newStackPtr = topPtr.get();
        origStackPtr = origStackPtr->getNext().get();

        while (origStackPtr) {
            newStackPtr->setNext(
                std::make_unique<Node<ItemType>>(origStackPtr->getItem())
            );
            newStackPtr = newStackPtr->getNext().get();
            origStackPtr = origStackPtr->getNext().get();
        }
    } catch (const std::bad_alloc&) {
        topPtr.reset(); // 智能指针自动释放所有已分配资源
        throw;
    }
}

template <typename ItemType>
bool LinkedStack<ItemType>::isEmpty() const {
    return !topPtr;
}

template <typename ItemType>
bool LinkedStack<ItemType>::push(const ItemType& newItem) {
    try {
        topPtr = std::make_unique<Node<ItemType>>(newItem, std::move(topPtr));
    } catch (const std::bad_alloc&) {
        return false;
    }
    return true;
}

template <typename ItemType>
bool LinkedStack<ItemType>::pop() {
    if(!isEmpty()) {
        auto nodeToDelete = std::move(topPtr);
        topPtr = std::move(const_cast<std::unique_ptr<Node<ItemType>>&>(nodeToDelete->getNext()));
        return true;
    }
    return false;
}

template <typename ItemType>
ItemType LinkedStack<ItemType>::peek() const {
    if (isEmpty()) {
        std::string message("LinkedStack::peek() ");
        message += "called on an empty stack.";
        throw PrecondViolatedExcep(message);
    }
    return topPtr->getItem();
}

关键改造说明

  • 采用std::unique_ptr管理节点所有权,无循环引用风险,内存开销与原始指针基本一致
  • 所有节点创建使用std::make_unique,完全消除显式new操作
  • 移除手动析构函数,智能指针自动递归释放所有节点资源
  • pop函数中通过所有权转移的方式销毁节点,无需手动调用delete
  • 仅在遍历节点时使用get()获取临时观察指针,未声明任何持有所有权的原始指针变量

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.26 06:24:08