C ++ функция автоматического вызова после изменения переменной - PullRequest
8 голосов
/ 01 июля 2010

Есть ли в c ++ функция, чтобы при изменении переменной она автоматически вызывала функцию?

Ответы [ 7 ]

13 голосов
/ 01 июля 2010

Есть ли в c ++ функция, чтобы при изменении переменной она автоматически вызывала функцию?

Нет, не то чтобы я могла придумать.Вы можете, однако, обернуть доступ к переменной в подходящей оболочке, которая позволяет вам подключиться к назначению.
Примерно так:

//Beware, brain-compiled code ahead!
template<typename T>
class assignment_hook {
public:
  typedef void (hook_t)(const T& old_value, const T& new_value);

  assignment_hook(T& value, hook_t hook) : ref_(value), hook_(hook)  {}

  T& operator=(const T& rhs)
  {
     hook_(ref_,rhs);
     ref_ = rhs;
  }
private:
  // I'd rather not want to think about copying this
  assignment_hook(const assignment_hook&);
  void operator=(const assignment_hook&);

  T& ref_;
  hook_t hook_;
};

Как отметил Ной в комментарии,

typedef boost::function<void(const T&,const T&)> hook_t;

(или, если он есть у вашего компилятора, std::tr1::function или std::function) значительно улучшит это, поскольку позволяет вызывать все виды "совместимых" функций.(Например, он позволяет использовать все виды магии, используя boost/std::/tr1::bind<> для вызова функций-членов и еще много чего.)

Также обратите внимание, что, как сказал adf88 в своих комментариях, он просто выполняет то, о чем просил (контролировать доступ на записьпеременной) и ни в коем случае не является полноценной реализацией свойства.На самом деле, несмотря на отношение C ++ к максимально возможной реализации в библиотеках и как можно меньше в языке, и, несмотря на попытки многих людей (некоторые из них довольно умные), никто не нашел способа реализовать свойства в C ++ как библиотека , без поддержки языка.

9 голосов
/ 01 июля 2010

одним словом; нет.

Но что вам нужно сделать, это заключить переменную в класс (я не собираюсь предлагать перегрузку операторов) и изменить ее с помощью функции set (...). Затем вы просто вызываете функцию из заданной функции.

3 голосов
/ 01 июля 2010

Вы можете сделать переменную приватной для некоторого класса, а затем использовать функции-члены для изменения.

Вы можете поместить свой дополнительный код в саму функцию-член, или вы можете выделить этот код отдельно и заставить функцию-член вызывать его при изменении.

2 голосов
/ 01 июля 2010

Нет, вы должны заключить переменную в пару методов get / set.

1 голос
/ 01 июля 2010

В зависимости от сложности вашей программы, вы можете использовать Слушатели, которые отслеживают определенные объекты на предмет изменений состояния, а другие части вашей программы подписываются на события от этого слушателя.

Однако лучшим вариантом будетпоместить эту функциональность в метод установки для этой переменной.Это может быть функция слушателя или прямой вызов функции.

0 голосов
/ 01 июля 2010

Если переменная имеет тип класса, вы можете перегрузить ее функцию operator =().Вы не можете сделать это, если переменная имеет примитивный тип.

0 голосов
/ 01 июля 2010

Вы можете инкапсулировать эту переменную и получать прослушиватели, которые уведомляются об изменении значения.Я бы пошел с boost :: сигналы или Boost :: сигналы2 для этого:

http://www.boost.org/doc/libs/1_43_0/doc/html/signals2.html

и вот некоторая информация о шаблоне наблюдателя: http://en.wikipedia.org/wiki/Observer_pattern

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...