Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Am I exposing too many iterators?

Tags:

c++

iterator

My class can have children and so I need to expose iterators. The render class needs to reverse iterate them which is why I have reverse iterators. But is there a way to have less of these because it seems like a lot:

std::vector<AguiWidget*>::iterator          getChildBeginIterator();
std::vector<AguiWidget*>::reverse_iterator  getChildRBeginIterator();
std::vector<AguiWidget*>::iterator          getChildEndIterator();
std::vector<AguiWidget*>::reverse_iterator  getChildREndIterator();

std::vector<AguiWidget*>::const_iterator            getChildBeginIterator() const;
std::vector<AguiWidget*>::const_reverse_iterator    getChildRBeginIterator() const;
std::vector<AguiWidget*>::const_iterator            getChildEndIterator() const;
std::vector<AguiWidget*>::const_reverse_iterator    getChildREndIterator() const;

std::vector<AguiWidget*>::iterator          getPrivateChildBeginIterator();
std::vector<AguiWidget*>::reverse_iterator  getPrivateChildRBeginIterator();
std::vector<AguiWidget*>::iterator          getPrivateChildEndIterator();
std::vector<AguiWidget*>::reverse_iterator  getPrivateChildREndIterator();

std::vector<AguiWidget*>::const_iterator            getPrivateChildBeginIterator() const;
std::vector<AguiWidget*>::const_reverse_iterator    getPrvateChildRBeginIterator() const;
std::vector<AguiWidget*>::const_iterator            getPrivateChildEndIterator() const;
std::vector<AguiWidget*>::const_reverse_iterator    getPrivateChildREndIterator() const;

Thanks

like image 663
jmasterx Avatar asked Mar 11 '11 13:03

jmasterx


1 Answers

Those look fine to me. Or I can't comment more precisely without knowing what exactly you're doing. But one thing you can surely do at any rate: why don't you use typedef? If you use typedef, you can use it outside the class as well, means in the client code, where you would use the class!

For example,

class sample
{
public:

  //make these typedef public so you use it from outside!
  typedef std::vector<AguiWidget*>::iterator  iterator ;
  typedef std::vector<AguiWidget*>::reverse_iterator reverse_iterator;
  typedef std::vector<AguiWidget*>::const_iterator const_iterator;
  typedef std::vector<AguiWidget*>::const_reverse_iterator const_reverse_iterator;

  iterator           child_begin();
  reverse_iterator   child_rbegin();
  iterator           child_end();
  reverse_iterator   child_rend();

  const_iterator            child_begin() const;
  const_reverse_iterator    child_rbegin() const;
  const_iterator            child_end() const;
  const_reverse_iterator    child_rend() const;
};

//Usage
sample s;
sample::iterator it= s.child_begin(); 
//see this ^^^^^^^^ how we use the typedef here!

This looks better! Basically the typedef encapsulates the implementation, because it helps you hide the implementation detail of the class; for example, what container you're using in the class, std::vector, std::list, or what? See again the Usage illustration above; just by looking at it you cannot say the container type, can you?

Note also that I changed the function name as well. I think that is fine. After all, STL uses just begin and end as opposed to beginIterator, and endIterator. However, the lower-case is my taste, you may still prefer upper-case for consistency!

In my opinion, the const functions don't make much sense, you probably would like the following set of functions if you want to expose readonly iterators!

const_iterator            readonly_child_begin();
const_reverse_iterator    readonly_child_rbegin();
const_iterator            readonly_child_end();
const_reverse_iterator    readonly_child_rend();


//Usage
sample s;
sample::const_iterator cit= s.readonly_child_begin(); 
//see this ^^^^^^^^ how we use the typedef here!
like image 120
Nawaz Avatar answered Sep 19 '22 12:09

Nawaz