На данный момент давайте предположим, что вы уверены в этом: ComponentA
владеет набор указателей, std::set<Thing *>
, и вы хотите, чтобы иметь метод, чтобы вернуть этот набор, но так, что принимающий клиентский код не может изменить Это. Вы не уверены в следующем:
- Верните копию комплекта.
- Верните ссылку на комплект.
- Возврат [
begin()
, end()
).
Не делайте этого. У каждого есть недостаток, который вы идентифицировали, и имеет дополнительный недостаток, который он не возвращает набор. Клиент код, получающий диапазон итераторов, не будет знать, что он ограничивает набор и не сможет воспользоваться определяющими свойствами набора.
Вместо возврат const
ссылки на набор из метода const
:
struct ComponentA
{
...
...
std:set<Thing *> const & get_set_of_things() const {
return things;
}
private:
std::set<Thing *> things
...
};
Это устраняет недостаток - клиентский код не может изменить набор через в const
ссылки - и не имеет никаких других помех.
Я надеюсь, что ответит на ваш вопрос, , но я боюсь, что это еще не конец ваших проблем с дизайном.
Код клиента не может изменить things
через std:set<Thing *> const &
, возвращенный get_set_of_things()
. Но вещи, которые я не могу изменить, являются членами этого набора, которые всего лишь указатели до Thing
. Мне, конечно, все равно, что эти указатели - адреса памяти, такие как 0x1a04c20
- и я не заинтересован в изменении их. Но ничего останавливает меня от изменения любого из Things
, что эти указатели указывают на, например.
ComponentA ca;
...
auto const & things = ca.get_set_of_things;
Thing * pthing = *things.begin();
thing->modify();
...
Это изменяет один из Things
контролируемой ca
- что то, что вы хотите предотвратить.
Однако вы возвращаете набор из ComponentA
объекта, вы не можете предотвратить клиента от модификации Things
под контролем объекта до тех пор, как вы даете им Thing *
-pointers.
Ну вы могли бы блокировать эту угрозу путем изменения things
к набору const
указателей:
struct ComponentA
{
...
...
std:set<Thing const *> const & get_set_of_things() const {
return things;
}
private:
std::set<Thing const *> things
...
};
Но выпадению этого изменения является то, что в настоящее время ComponentA
сама не может изменять любого из Things
контролируется things
. Можете ли вы с этим жить?
И это только первый из нескольких громких дизайнерских тревог, которые вызываются информацией, что ваш ComponentA
контролирует набор указателей. Я предлагаю вам создать определение вашего класса и поставить его для комментария на сайте-партнере SO Code Review. Это выходит за рамки SO, чтобы исследовать все вероятные подводные камни, особенно при отсутствии какого-либо кода.
Что нужно пользователям API? Должны ли они даже знать, что это набор? – doctorlove