Jump to content
  • Advertisement
Sign in to follow this  
Sean_Seanston

Traversing another class' private vector?

This topic is 3175 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I've come into a bit of a problem with a private vector. I have 2 classes: A has a private vector of pointers. B needs to access each one of those pointers. I don't want to make the vector public since it probably should be private since it shouldn't be able to be cleared or have anything added to it from outside. I need B to somehow be able to traverse the vector and access the pointers or at least access them all somehow. How can I do that? I had some idea of passing in an iterator in an accessing function but since B doesn't know the size of the private vector, I quickly scrapped that. Would it be best just to pass a vector within B to a function in A and have that function copy all elements from the private vector to the temporary vector of B? [Edited by - Sean_Seanston on March 7, 2010 11:31:17 AM]

Share this post


Link to post
Share on other sites
Advertisement
putting
friend class B;



anywhere in the declaration of class A will make every private/protected member accessible (only) for class B.
is that what you need?

ps: there are some things with the friend "relationship" you should know of and I can't find a good tutorial/paper anywhere so I'll try to recall them myself:
1) It's a one-way "relationship" if B is a friend of A, A isn't a friend of B.
2) classes that inherit from B are not friend with A (not 100% sure though).
3) you can also only declare functions as friend:
friend void doFoo(int);
friend int B::justAFunction();


Share this post


Link to post
Share on other sites
Quote:
Original post by Sean_Seanston
B needs to access each one of those pointers.


Why?

Share this post


Link to post
Share on other sites
struct Container {
template < class Visitor >
void visit(Visitor v) {
std::for_each(foos.begin(), foos.end(), v);
}
private:
std::vector<Foo*> foos;
];

Share this post


Link to post
Share on other sites
Quote:
Original post by Zahlman
Quote:
Original post by Sean_Seanston
B needs to access each one of those pointers.


Why?


It needs to get an identifier from the objects that are pointed to, so that it can initialize some objects.

A is a Flyweight for B.

Share this post


Link to post
Share on other sites
Quote:
Original post by Antheus
struct Container {
template < class Visitor >
void visit(Visitor v) {
std::for_each(foos.begin(), foos.end(), v);
}
private:
std::vector<Foo*> foos;
];


This is still somewhat less flexible than just exposing an iterator to the container. For example:


class Foo
{
typedef std::vector<int> ItemList_t;

private:
ItemList_t items;

public:
ItemList_t::iterator begin() { return items.begin(); }
ItemList_t::iterator end() { return items.end(); }
ItemList_t::const_iterator begin() const { return items.begin(); }
ItemList_t::const_iterator end() const { return items.end(); }
};





For one thing, it's less code because unless your compiler supports C++0x lambdas (or you already have written a function whose sole purpose is to perform the operation of interest on these pointers) you're going to have to create a class to operate on them and then use it as a function object. This usually ends up being a lot of code for such simple matters, and creating thousands of little function objects for highly specialized purposes ends up not being very scalable in the long run.

Secondly, it allows you to base your logic on complicated relationships between the objects, with the simple visit approach each entry in the list is treated independently of the others. For example, suppose for whatever strange reason you wanted to do the following, assuming you've defined iter and end to refer to vec.begin() and vec.end() respectively.


while (iter != end)
{
iterator next = iter;
++next;
if (next != end)
do_something_weird(*iter, *next);

iter = next;
}




It's *possible* with the function object approach, but it's already kind of unintuitive and rapidly starts becoming less and less intuitive as you change things / make things more complicated.

For these and probably other reasons which aren't immediately popping into my head, I've adopted a pretty much universal approach of just always exposing the iterator type via a public typedef and then return both iterators and const_iterators from the class.

Share this post


Link to post
Share on other sites
Can you have a method on A that returns the vector by const reference? More than just B would be able to see it, but you wouldn't have to write any boilerplate.
typedef std::vector<Foo*> FooVec;

class A{
FooVec vec;
public:
const FooVec& GetVec() const{ //provides read-only access to the vector
return vec;
}
};

void UseVector(A& a){
const FooVec& vec = a.GetVec();
//The function can read the vector,
//but can't write it because it is const
//even if the A object isn't
}

Share this post


Link to post
Share on other sites
Hmmm... I hadn't thought of that Ocelot, that seems like it might be less fiddly than cache_hit's way for my purposes.

Well, I implemented the way cache_hit suggested and that worked fine, thanks. Maybe I'll have a look at returning a const reference too. It might be quicker than making 2 iterators wherever I need to do this. Unless someone points out a fatal flaw or something.

Share this post


Link to post
Share on other sites
Keep in mind that if you expose the internal vector, either through const_iterators or a const reference to the vector, while you won't be able to alter the vector contents, you will allow external actors to call non-const member functions on those pointers.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!