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

如何用unique_ptr替代原始指针实现C++迭代器设计模式?

问题与解决方案:迭代器模式中替换原始指针为unique_ptr

问题根源

你写的CreateIterator2函数存在两个关键错误:

  • 构造参数错误:直接把Container的this指针传给unique_ptr<Iterator>的构造函数,属于类型不匹配——unique_ptr需要接收Iterator类型的指针,而非Container指针。
  • 调用语法错误:客户端代码里的unique_ptr声明缺少闭合的尖括号,导致编译失败。

修正方案

1. 正确实现CreateIterator2

使用std::make_unique(C++14及以上)直接创建并返回unique_ptr<Iterator>,这是最安全的方式;也可以显式new一个Iterator后交给unique_ptr管理,但make_unique更推荐,避免裸new。

2. 修正客户端调用语法

补全unique_ptr声明的闭合尖括号,确保语法正确。

3. 移除手动delete操作

unique_ptr会在生命周期结束时自动释放内存,无需手动调用delete。

完整修正代码

// refactoring.guru c++ design patterns
#include <iostream>
#include <string>
#include <vector>
#include <memory>

template<typename T, typename U>
class Iterator {
public:
    typedef typename std::vector<T>::iterator iter_type;

    Iterator(U* p_data, bool reverse = false) : m_p_data_(p_data) {
        m_it_ = m_p_data_->m_data_.begin();
    }

    void First() {
        m_it_ = m_p_data_->m_data_.begin();
    }

    void Next() {
        m_it_++;
    }

    bool IsDone() {
        return (m_it_ == m_p_data_->m_data_.end());
    }

    iter_type Current() {
        return m_it_;
    }

private:
    U* m_p_data_;
    iter_type m_it_;
};

template<class T>
class Container {
    friend class Iterator<T, Container>;

public:
    void Add(T a) {
        m_data_.push_back(a);
    }

    Iterator<T, Container>* CreateIterator() {
        // 原始实现,使用裸new
        return new Iterator<T, Container>(this);
    }

    // 修正后的智能指针版本
    std::unique_ptr<Iterator<T, Container>> CreateIterator2() {
        // 使用make_unique创建并返回unique_ptr,避免裸new
        return std::make_unique<Iterator<T, Container>>(this);
        // 兼容C++11的写法:return std::unique_ptr<Iterator<T, Container>>(new Iterator<T, Container>(this));
    }

private:
    std::vector<T> m_data_;
};

class Data {
public:
    Data(int a = 0) : m_data_(a) {}

    void set_data(int a) {
        m_data_ = a;
    }

    int data() {
        return m_data_;
    }

private:
    int m_data_;
};

void ClientCode() {
    std::cout << "________________Iterator with int______________________________________" << std::endl;
    Container<int> cont;

    for (int i = 0; i < 10; i++) {
        cont.Add(i);
    }

    // 原始裸指针用法
    Iterator<int, Container<int>>* it = cont.CreateIterator();
    for (it->First(); !it->IsDone(); it->Next()) {
        std::cout << *it->Current() << std::endl;
    }
    delete it; // 手动释放

    // 修正后的unique_ptr用法
    std::unique_ptr<Iterator<int, Container<int>>> it_ptr = cont.CreateIterator2();
    for (it_ptr->First(); !it_ptr->IsDone(); it_ptr->Next()) {
        std::cout << *it_ptr->Current() << std::endl;
    }
    // 无需手动delete,unique_ptr自动管理


    Container<Data> cont2;
    Data a(100), b(1000), c(10000);
    cont2.Add(a);
    cont2.Add(b);
    cont2.Add(c);

    std::cout << "________________Iterator with custom Class______________________________" << std::endl;
    // 同样替换为unique_ptr
    std::unique_ptr<Iterator<Data, Container<Data>>> it2_ptr = cont2.CreateIterator2();
    for (it2_ptr->First(); !it2_ptr->IsDone(); it2_ptr->Next()) {
        std::cout << it2_ptr->Current()->data() << std::endl;
    }
}

int main() {
    ClientCode();
    return 0;
}

关键说明

  • std::make_unique会自动分配内存并构造对象,返回对应的unique_ptr,完全避免了裸指针的使用,更符合现代C++的内存管理规范。
  • unique_ptr是独占式智能指针,确保同一时间只有一个指针管理对象内存,生命周期结束时自动调用析构函数释放资源,彻底消除内存泄漏风险。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.23 11:37:06