I have a class which has a std::vector of child control pointer. For obvious reasons, I do not want the user of the class to have direct access to the std::vector. All I would want is a way to give the caller the pointers. What would be a good OO way to do this? (this function will be called often)
Thanks
Provide a function that returns a const_iterator
to the vector. It is also useful to add one to return the iterator to the end of the vector.
class MyClass {
public:
typedef vector<T>::const_iterator c_iter;
c_iter getBegin() const {return v.begin();}
c_iter getEnd() const {return v.end();}
// and perhaps if it's useful and not too invasive.
const T& getAt(int i) const {return v.at(i);}
//stuff
vector<T> v;
};
Iterators are a good, obvious way to do this. A visitor pattern is another way to give the client code the ability to operate on each element in the vector: in some ways it's even cleaner, exposing less to the user, and allowing the container more control, e.g.:
BUT
begin()
, incremented or not, as well as other operations like find()
: this is a cleaner factoring of functionality.That would look something like:
class Container
{
public:
template <typename Visitor>
void visit(Visitor& visitor)
{
for (Vector::const_iterator i = v_.begin(); i != v_.end(); ++i)
visitor(*i);
}
private:
typedef std::vector<X> Vector;
Vector v_;
};
// client code...
struct Visitor
{
void operator()(const X&) { ... }
// any data you want to update as you iterate...
};
Visitor v(...any construction arguments...);
container.visit(v);
I usually do it something like the following:
class MyClass {
public:
const unsigned int GetNumberOfItems() { return v.size(); }
T* GetItemNumber(const unsigned int n)
{
// 3 options here, thrown your own exception type, or use the std one, or
// or just return NULL meaning nothing there or out of range.
try{
return v.at(n);
} catch (std::out_of_range &e){
}
return NULL;
}
vector<T> v;
};
Then you can just do something like:
MyClass cl;
int count = cl.GetNumberOfItems();
for (int i = 0; i < cl.GetNumberOfItems(); i++){
T* item = cl.GetItemNumber(i);
}
No iterators to the outside world required. If you have ever have to expose something like this to a standard C API then it's very easy to expose.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With