如何用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
相关产品推荐
相关产品推荐

