tags:

views:

85

answers:

3

I'm dealing specifically with C++, but this is really language-agnostic.

Just to give some context into the problem... I have a tree/graph based structure where each node holds a collection of multiple items.

I have a class which encapsulates some generic collection (list, map, vector, LinkedList, whatever). I want to be able to fetch all the items from that collection in the most efficient way possible without the client being able to edit the private collection.

Here is a simplified example of what I have:

class MyClass
{
public:
    // Basic constructors and such
    void AddItem(int item) { _myItems->push_back(item); }

private:
    list<int>* _myItems;
};

So obviously a getter which retrieves the pointer to _myItems does not work as this will allow the client to edit _myItems.

Attempt 1:
I could create a new list and return a pointer to that one instead... however I don't like that idea as the responsibility of creating and deleting now lie with different objects.

Attempt 2:
I'm thinking it would be best to create some CopyTo methods such as:

void CopyItemsToList(list<int>* inList) { // copy the items to client list }

This way, the client takes care of mem management and it is easy to extend this to allow more data structures. My concern with this approach is cost... The list can be very big, and the cost of copying the items could get large

Attempt 3:
Instead of keeping a pointer to a list in the class, just use a value type and return that (letting the copy constructor take care of it). But, this seems like the performance cost will be the same as #2...

Anyways, any other way to go about this? Let me know what you guys think... Thanks.

+6  A: 

The Iterator pattern is generally considered a proper method to expose a list of elements from a collection agnostic to the actual internal representation of the collection. You could create your iterator in such a way that it returns read-only (const) references, or make copies of items on the fly as they're requested instead of copying the entire list.

Amber
const_terator then, so clients can't modify the element itself, if that's the requrement.
Eugene
Correct; updated answer to be a bit more explicit about that.
Amber
Meh. Sounds like a lot of work considering the bulk of the data is built around a list that can already be iterated through.
Kieveli
My answer was based on this: "I have a class which encapsulates some generic collection (list, map, vector, LinkedList, whatever)." From that wording, it seems like the encapsulated data might potentially change, and it's a lot more flexible to provide an external representation which is agnostic to the internal representation so that if the internal representation ever changes, the things using the wrapper class do not.
Amber
I figured it would be something like this... I just wanted to keep my project as simple as possible :(
Polaris878
+2  A: 

You can return const reference to your list instead of a pointer (or just pointer to const). Client will still be able to const cast it, but this would be their own problem then.

const list<int>& GetList() const { return *_myItems; }
Eugene
This exposes implementation details outside the class. Thus tightly binding any user of the class to your implementaion detail. BAD....
Martin York
Use private implementation pattern and move getter code out of header. But yeah, iterators are the true way.
Eugene
A: 

Just return a copy of the list:

list<int> GetList() { return *_myItems; }

Don't optimize prematurely. It's the root of all evil.

Kieveli