2

我创建了一个这样的类

class myClass {

public:  
 int addMeOne; 
 void Invoked()  { .... }
};

我创建了它的一个对象,并通过引用将它发送到我程序的所有其他模块。每个人都习惯将 addMeOne 变量增加 1 。有些人甚至习惯添加两次,但这不是重点。

有了这个,现在我希望每当有人更改 addMeOne 时,我的函数 Invoked() 应该被调用。

请注意,正确的策略是我应该允许 addMeOne 被某个函数暴露在外部,而在该函数内部我可以调用 Invoked 。但是,现在无法更改接口,因为它现在已向所有其他人公开并且不应修改。我该如何纠正这个。?

4

5 回答 5

0

你需要阅读封装。如果不提供锁定的 getter / setter 接口,addMeOn就无法保证对其使用的控制。

不要害怕改变界面。对于任何使用它来改变的人来说,这不是一项艰巨的任务,他们应该清楚你在改变它时所做的事情是为他们的利益提供价值。

于 2012-08-30T14:32:07.200 回答
0

使用可以变成addMeOne代理。

class myClass 
{
    class addMeOneProxy
    {
        public:
            addMeOneProxy(myClass &s) : parent(s) {}

            // This gets called whenever something tries to use the addMeOne 
            // member variable as an integer.
            operator int() const 
            {
                return parent.addMeOne;
            }

            // This gets called whenever something assigns a value to addMeOne.
            int operator=(int val) 
            {
                parent.Invoked(); 
                return val;
            }

            // You could also implement an operator++ or whatever else you need.

        private:
            myClass &parent;
    };

  public:
    void Invoked();
    addMeOneProxy addMeOne;
};

当然,如果您决定在某个时候将 Invoked() 设为私有,则需要将 myClass 设为 addMeOneProxy 的朋友类,以便 addMeOneProxy 可以调用 Invoked 成员函数。

我当然同意其他评论者的观点,即你真的应该为此拥有 getter 和 setter 函数,但我也理解开发人员通常控制和改变他们所生活的世界的权力有限。所以,代理就是你如何做到这一点,如果你不能也不能改变世界。

于 2012-08-30T14:38:09.017 回答
0

您必须创建一个将值分配给addMeOne变量的方法,这称为 setter 方法,并将变量本身设为私有。

我相信,在更改整数变量时无法触发函数。

一种改变接口但不需要改变外部代码的替代方法是定义一个模拟整数行为的类,即实现operator++等,并更改addMeOne为这种类型。

于 2012-08-30T14:30:07.107 回答
0

真的,可能值得告诉所有客户使用方法而不是公共变量。您要么需要更改类、客户端或两者。

没有办法解决它。再做一次,做对。接受打击。

有一些技巧:一旦你公开了一个成员变量,你可以做的一件事就是int addMeOne用其他一些具有相同名称但不同类型的变量替换。countedint addMeOne. 您必须编写的countedint类使其行为类似于 int,但赋值、递增等也计算它们被使用的次数。例如

countedint & operator ++(){
   m_value++;
   m_number_of_uses++;
   return *this;
}
countedint & operator --(){
   m_value--;
   m_number_of_uses++;
   return *this;
}

您可能还需要对 int 使用强制转换运算符,并且您也可以计算那里的使用次数。

于 2012-08-30T14:32:36.340 回答
0

您应该保留此类的 ABI,还是只保留其客户使用的语法?如果您可以更改 的类型addMeOne,保留编写能力addMeOne++等,您可以定义一个类和相关的运算符 - 然后使其addMeOne成为此类的一个实例。当然,现在addMeOne操作员可以做任何事情——包括调用一些MyClass成员函数。

伪代码:

class Proxy
{
public:
  Proxy(YourClass *parent) : parent_(parent), value_(0)
  {}
  void operator++() 
  {
    ++value_;
    // doAnything with parent_
  }
  // accessors, cast operators etc...
private:
  YourClass *parent_;
  int value_;
};

class YourClass
{
public:
  YourClass() : addMeOne(this)
  {}
  Proxy addMeOne;
};
于 2012-08-30T14:33:38.103 回答