【问题标题】:Automatically call function when variable changes变量变化时自动调用函数
【发布时间】:2010-07-01 15:17:57
【问题描述】:

c++中有没有办法在变量值改变时自动调用函数?

【问题讨论】:

    标签: c++ function


    【解决方案1】:

    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::functionstd::function)会大大改善这一点,因为它允许调用各种“兼容”函数。 (例如,它可以使用boost/std::/tr1::bind&lt;&gt; 调用成员函数等各种魔法。)

    还请注意,正如 adf88 在他的 cmets 中所说,这只是执行所要求的(监视对变量的写访问),绝不是一个成熟的属性实现。事实上,尽管 C++ 的态度是在库中尽可能多地在语言中实现,尽管有很多人(其中一些相当聪明的人)尝试过,但没有人找到在 C++ 中实现属性的方法作为一个库,没有语言的支持。

    【讨论】:

    • 你不觉得太复杂了吗?其他运营商呢?拿个地址怎么办?你在这里刹车语义。如果编译器不支持属性,那么模拟它们不是一个好的解决方案。 -1
    • @adf88:“太复杂”是什么意思?如果你想按照提问者的要求去做,那么这很简单。至于您的最后一点,编译器不直接支持可调整大小的数组、函数对象、智能指针、模板元编程或许多其他通过编写代码来“模拟”它们已成为常见(甚至标准)C++ 习惯用法的概念。
    • 使用 boost::function 和/或 boost::signals(2) 会使这成为更好的解决方案恕我直言。
    • 覆盖 = 运算符..多么酷的技巧。恕我直言,比 Java 污染思维推荐的 getter/setter hack 要好得多。在一些 Java 项目中,我一直在与 getter/setter 垃圾作斗争,并且一直希望我们可以像上面一样覆盖 = 运算符。一个很好的例子是你在运行时设置一次的变量,如果再次设置就会抛出异常。
    • @User1:如果你只允许设置/赋值一次,为什么不简单地把它放在构造函数中呢?
    【解决方案2】:

    一句话;没有。

    但是你应该做的是将变量包装到一个类中(我不建议运算符重载),并通过 set(...) 函数对其进行更改。然后你只需从 set 函数中调用该函数。

    【讨论】:

    • 一句话:是的。通过适度的努力,侦听器可以监视变量在多线程程序中的变化并相应地调用函数。即使在非多线程系统中,它也可以工作,尽管它有点像 hack。我并不是说我推荐它,因为 setter 选项(可能)更好,但说它不能完成是完全不正确的。
    • @glow 这听起来不像 C++ 中包含的函数,这似乎是 OP 要求的
    • @Michael 这根本不是我的解释。听起来他希望能够在某些事情发生变化时调用函数,并在 C++ 中执行此操作。至少在这些人看来,它似乎没有指定是否内置。
    • @glow 我猜他可能会对任何解决方案感到满意,但是“C++ 中有没有函数”让我觉得他只是想打电话给detect_changes(&amp;var, my_function_pointer);
    【解决方案3】:

    您可以将变量设为某个类的私有变量,然后首先使用成员函数进行更改。

    您可以将额外代码放入成员函数本身,或者您可以将该代码分开并让成员函数在更改时调用它。

    【讨论】:

      【解决方案4】:

      不,您应该将变量封装在几个 get/set 方法中。

      【讨论】:

        【解决方案5】:

        根据程序的复杂性,您可以使用监听器来监视某些对象的状态变化,并让程序的其他部分订阅来自该监听器的事件。

        但是,最好的选择是将此功能放入该变量的 setter 方法中。它可以是侦听器功能,也可以是直接函数调用。

        【讨论】:

          【解决方案6】:

          如果变量具有类类型,则可以重载其operator =() 函数。如果变量是原始类型,则不能这样做。

          【讨论】:

            【解决方案7】:

            您可以封装该变量,并让侦听器在值更改时收到通知。我会选择 boost::signals 或 boost::signals2 :

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

            这里有一些关于观察者模式的信息: http://en.wikipedia.org/wiki/Observer_pattern

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 2019-03-01
              • 2019-10-05
              • 1970-01-01
              • 2011-12-18
              • 2011-09-08
              • 2021-11-27
              • 2021-09-01
              相关资源
              最近更新 更多