I've got this fairly simple C++ code from refactoring.guru. It compiles and works as expected. However, it uses new
and delete
via the CreateIterator()
member function, and I'd like to port it to use unique_ptr
, but I'm not sure how to do that exactly.
I've created a CreateIterator2()
function using unique_ptr
, which compiles (I think this is what I want), but not if I invoke it, so I commented out the invocation.
I'm not sure what I am missing to return a smart pointer and avoid using raw new
/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() {
// want to avoid this
return new Iterator<T, Container>(this);
}
//think this is what I want - compiles
std::unique_ptr<Iterator<T, Container>> CreateIterator2() {
return std::unique_ptr<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;
}
//THIS DOESN"T COMPILE
//std::unique_ptr<Iterator<int, Container<int>> it = cont.CreateIterator2();
//for (it->First(); !it->IsDone(); it->Next()) {
// std::cout << *it->Current() << std::endl;
//}
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;
Iterator<Data, Container<Data>>* it2 = cont2.CreateIterator();
for (it2->First(); !it2->IsDone(); it2->Next()) {
std::cout << it2->Current()->data() << std::endl;
}
//avoid this
delete it;
delete it2;
}
int main() {
ClientCode();
return 0;
}
Aucun commentaire:
Enregistrer un commentaire