У меня есть класс complicated
, в котором есть различные сеттеры, которые изменяют некоторое внутреннее состояние. Эта внутренняя модификация состояния потенциально дорогая, поэтому я хочу делать это не слишком часто. В частности, если несколько сеттеров будут вызваны сразу, я хочу выполнить дорогостоящее обновление внутреннего состояния только один раз после последнего из этих вызовов сеттера.
Я решил (или «решил»?) Это требование с помощью прокси. Ниже приведен пример минимального рабочего кода:
#include <iostream>
class complicated
{
public:
class proxy
{
public:
proxy(complicated& tbu) : to_be_updated(&tbu) {
}
~proxy() {
if (nullptr != to_be_updated) {
to_be_updated->update_internal_state();
}
}
// If the user uses this operator, disable update-call in the destructor!
complicated* operator->() {
auto* ret = to_be_updated;
to_be_updated = nullptr;
return ret;
}
private:
complicated* to_be_updated;
};
public:
proxy set_a(int value) {
std::cout << "set_a" << std::endl;
a = value;
return proxy(*this);
}
proxy set_b(int value) {
std::cout << "set_b" << std::endl;
b = value;
return proxy(*this);
}
proxy set_c(int value) {
std::cout << "set_c" << std::endl;
c = value;
return proxy(*this);
}
void update_internal_state() {
std::cout << "update" << std::endl;
expensive_to_compute_internal_state = a + b + c;
}
private:
int a;
int b;
int c;
int expensive_to_compute_internal_state;
};
int main()
{
complicated x;
x.set_a(1);
std::cout << std::endl;
x.set_a(1)->set_b(2);
std::cout << std::endl;
x.set_a(1)->set_b(2)->set_c(3);
}
Он производит следующий вывод, который выглядит именно так, как я хотел:
set_a
обновление
set_a
set_b
обновление
set_a
set_b
Set_C
обновление
Мои вопросы: Законен ли мой подход / лучшая практика?
Можно ли полагаться на временные объекты (т. Е. proxy
возвращаемые объекты), которые будут уничтожены в точке с запятой?
Я спрашиваю, потому что по какой-то причине у меня плохое предчувствие. Может быть, мое плохое предчувствие связано с предупреждением Visual Studio, которое гласит:
Предупреждение C26444 Избегайте неназванных объектов с пользовательской конструкцией и
уничтожение (es.84).
Но, может быть / надеюсь, мои плохие чувства неоправданны, и это предупреждение можно просто проигнорировать?
Что беспокоит меня больше всего: Есть ли случай, когда метод update_internal_state
НЕ будет вызван (возможно, из-за неправильного использования моего класса или из-за какой-то оптимизации компилятора или чего-то еще)?
Наконец: Есть ли лучший подход для реализации того, что я пытаюсь достичь с помощью современного C ++?