Предположим, у меня есть:
class Metadata {
// stores expensive-to-copy data, provides complex interface to access/modify
}
class SomeObject
public:
Metadata& GetMetadata() { return mMetadata; }
private:
Metadata mMetadata;
}
boost::shared_ptr<SomeObject> obj = ...;
obj->GetMetadata().SetTitle("foo");
obj->GetMetadata().GetTitle();
Всеобщее мнение, кажется, заключается в том, что возврат по ссылке, особенно неконстантный, крайне плох во всех, кроме нескольких конкретных ситуациях. Однако в данном случае это представляется лучшим (и единственным?) вариантом:
- Я не хочу возвращать копию, так как хочу изменить оригинал (и даже если это было r/o, копирование слишком дорого).
- Я не хочу возвращать метаданные* или что-то подобное, так как я не хочу поощрять сохранение или передачу указателя.
- Я не хочу загрязнять интерфейс SomeObject ненужными вызовами оболочки для метаданных.
Он вводит расплывчатое требование, чтобы SomeObject мог возвращать метаданные по ссылке, а это означает, что должен существовать объект метаданных, время жизни которого совпадает (или превышает) со временем жизни SomeObject, однако это точное семантическое отношение между объектами, и требование, что уж точно лучше, чем любой из вышеперечисленных вариантов.
Мне пришло в голову, что я мог бы ввести какой-то некопируемый тип указателя и вернуть его, но это пахнет забавно / кажется излишним. Я мог бы заставить SomeObject владеть boost::shared_ptr, но это действительно не очень хорошо соответствует семантике, которую я имел в виду (в основном: если вы изменяете сейчас, измените оригинал - если вы читаете позже/сохраняете, сделайте копию и следите за собой).
Есть ли лучший шаблон для использования здесь? Буду ли я стрелять себе в ногу каким-то образом, которого я не вижу?
Metadata
уже инкапсулирует необработанные данные, также может быть совершенно нормально просто сделатьmMetadata
общедоступным членомSomeObject
(желательно с лучшим именем) и использовать его напрямую, вместо того, чтобы проходить черезGetMetadata()
(который, похоже, ничего не дает). в таком случае). - person Jerry Coffin   schedule 24.10.2014Metadata
могут быть ненужными, но они не должны быть неуместными, иначеMetadata
не принадлежитSomeObject
. - person Chris Drew   schedule 24.10.2014