Ситуация: Я пытаюсь реализовать два класса, один из которых называется «специальный». special
имеет переменную-член bool conditions
и метод perform_special
,
Другой класс назван manager
и он имеет в качестве переменной-члена типа special
, я хочу manager
звонить perform_special
на его special
член только если condition
правда.
До сих пор я реализовал этот кусок кода:
#include<iostream>
using namespace std;
class special{
public:
special(){};
void perform_special();
void set_conditions( bool cond );
bool get_conditions();
private:
bool conditions;
};
void special::perform_special(){ cout<<"special performed."<<endl; }
void special::set_conditions( bool cond ){ conditions = cond; }
bool special::get_conditions(){ return conditions; }
class manager{
public:
manager(){};
void check_specials();
void set_effect( special* eff );
private:
special* effect;
};
void manager::check_specials(){
if(effect->get_conditions()){ effect->perform_special(); }
}
void manager::set_effect( special *eff ){ effect = eff; }
int main(){
int a=3; int b=2;
bool cond = a<b;
special effect1;
effect1.set_conditions( cond );
a=2; b=3;
manager manager1;
manager1.set_effect( &effect1 );
manager1.check_specials();
return 0;
}
Вот что он делает: он создает логическое значение cond
который сразу оценивается как false
потому что в этот момент, a<b
ложно Теперь он передает это условие специальной переменной, которая снова передается переменной менеджера. Когда менеджер звонит check_special
на его специальной переменной ничего не происходит, потому что cond
ложно
вот моя проблема: Я не хочу cond
Быть оцененным немедленно. Как вы можете видеть в коде, значения a и be могут изменяться и, следовательно, значение выражения a<b
, Как я могу достичь этого значения cond
оценивается только когда функция check_specials()
вызывается и использует последние значения переменных a и b?
Фон: Я пытаюсь реализовать текстовую приключенческую игру, поэтому «специальным» будет какой-то особый эффект, который произойдет, если будет выполнено множество условий. ‘manager’ — это своего рода мастер-класс, который обрабатывает игру и содержит все специальные эффекты и т. д. Я хочу объявить эти специальные эффекты в функции main и передать их переменной типа ‘game’ типа manager
а затем начать рутину игры, так что мне нужно manager
оценивать условные выражения для спецэффектов динамически, поскольку условия явно меняются со временем.
Вы могли бы построить Cond
класс, прототип с:
struct Cond
{
int& a;
int& b;
operator bool() const {return a < b;}
};
с которой вы бы создали
Cond cond{a, b};
вместо вашей текущей декларации cond
,
Вы бы тогда написать if (cond)
в точке тестирования, которая будет использовать текущие значения a
а также b
через ссылки.
Это медвежьи кости этого ленивого метода оценки, но это только начало. Основной ловушкой является потенциал для свисающие ссылки, возможно решить с std::reference_wrapper
,
Вы передаете переменную типа bool
к методу cond()
и переменная может содержать только значение. То, что вам нужно передать, это функция, которая возвращает bool
:
class special{
public:
using predicate = std::function<bool()>;
void set_conditions( predicate p );
...
};
теперь вы можете передать функцию, функтор, лямбду и т. д., которые будут оцениваться позже:
int main()
{
int a=3; int b=2;
auto cond = [&]{ return a<b; };
special effect1;
effect1.set_conditions( cond );
...
}