Классу принадлежит объект типа U
. Через метод он выставляет этот объект как const U&
, используя геттер (не дешевое копирование, модификация не желательна).
Теперь клиент хочет использовать этот API. Он хочет использовать экземпляр U
как часть сложного объекта (который не заинтересован в изменении объекта API).
Поэтому у него есть как минимум следующий вариант:
Создайте класс T
с const U&
в качестве параметра и закрытое поле типа const U&
, где конструктор хранит экземпляр API.
Это имеет крайний недостаток, заключающийся в том, что экземпляры класса становятся чрезвычайно негибкими (например, нет управления с использованием std :: vectors), что нежелательно.
Не так давно я обнаружил, что можно также использовать std::reference_wrapper<const U>
для хранения const U&
, что не налагает этих недостатков на экземпляры типа T
.
Вопрос теперь в том, ведет ли себя это так, как ожидается, и является ли это хорошей практикой?
Далее и здесь вы можете найти рабочий код, используя эту стратегию и описанные типы.
#include <iostream>
#include <memory>
class U{
public:
uint value;
};
class T{
private:
std::reference_wrapper<const U> _u;
public:
T(const U& u)
:_u(u) {}
const U& GetU(){
return _u;
}
};
const U& provideValue(U& u){
return u;
}
int main()
{
U internalApiValue;
internalApiValue.value = 5;
auto apiValue = provideValue(internalApiValue);
T container(apiValue);
std::cout << container.GetU().value;
}
Полагаю, если это не очень хорошая идея, единственной альтернативой было бы избегать использования const, поскольку в противном случае я бы наложил высокие ограничения на пользователей таких методов (методы, предоставляющие const U&
вместо U&
или U
)