Лучшая практика для получения коллекции предметов из объекта? - PullRequest
1 голос
/ 03 августа 2009

Я имею дело конкретно с C ++, но это действительно не зависит от языка.

Просто чтобы дать некоторый контекст в проблему ... У меня есть структура на основе дерева / графа, где каждый узел содержит коллекцию из нескольких элементов.

У меня есть класс, который инкапсулирует некоторую универсальную коллекцию (список, карта, вектор, LinkedList, что угодно). Я хочу иметь возможность извлекать все элементы из этой коллекции наиболее эффективным способом без возможности редактирования частной коллекции клиентом.

Вот упрощенный пример того, что у меня есть:

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

private:
    list<int>* _myItems;
};

Так что, очевидно, метод получения, который извлекает указатель на _myItems, не работает, поскольку это позволит клиенту редактировать _myItems.

Попытка 1:
Я мог бы создать новый список и вместо этого вернуть указатель на него ... однако мне не нравится эта идея, поскольку ответственность за создание и удаление теперь лежит на разных объектах.

Попытка 2:
Я думаю, что было бы лучше создать некоторые методы CopyTo, такие как:

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

Таким образом, клиент берет на себя управление записью, и его легко расширить, чтобы добавить больше структур данных. Меня беспокоит такой подход: стоимость ... Список может быть очень большим, а стоимость копирования предметов может увеличиться

Попытка 3:
Вместо того чтобы хранить указатель на список в классе, просто используйте тип значения и возвращайте его (позволяя конструктору копирования позаботиться об этом). Но, похоже, что производительность будет такой же, как # 2 ...

В любом случае, есть ли другой способ сделать это? Дайте мне знать, что вы, ребята, думаете ... Спасибо.

Ответы [ 3 ]

6 голосов
/ 03 августа 2009

Шаблон Iterator обычно считается правильным методом для представления списка элементов из независимой от коллекции фактического внутреннего представления коллекции. Вы можете создать свой итератор таким образом, чтобы он возвращал ссылки «только для чтения» (const), или делать копии элементов «на лету» по мере необходимости, а не копировать весь список.

2 голосов
/ 03 августа 2009

Вы можете вернуть константную ссылку на ваш список вместо указателя (или просто указатель на const). Клиент по-прежнему сможет использовать его, но тогда это будет его собственная проблема.

const list<int>& GetList() const { return *_myItems; }
0 голосов
/ 03 августа 2009

Просто верните копию списка:

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

Не оптимизируйте преждевременно. Это корень всего зла.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...