【问题标题】:General programming question about scope关于范围的一般编程问题
【发布时间】:2011-08-01 18:56:29
【问题描述】:

这更像是一个一般性的编程问题,所以我给出的代码示例只是伪代码。我用 C++、Java 和 Python 编程,所以伪代码是它们的混合体。我不太确定这个名字叫什么,所以如果你能给我一个名字,我可以谷歌了解更多关于它的信息,我将不胜感激。

假设我有一个名为 A 的类。在这个类中,我创建了一个名为 B 的类的实例:

class A {
    //instance variables
    classB;
    variable1;
    variable2;

    //instance methods
    instanceFunction(parameter1, parameter2) {
        //Do Stuff
    }

    function1(parameter1) {
        classB = new B(some parameters);
    }

    setVariable1(value) {
        variable1 = value;
    }

    getVariable2() {
        return variable2;
    }
}

在 B 类中,我想对 A 类中的实例变量进行更改或使用。我可以通过将 A 的引用传递给 B 来做到这一点。所以我的 A::function1 看起来像这样:

function1(parameter1) {
    variable1 = new B(this, other parameters);
    //Python syntax:
    //variable1 = B(self, other parameters)
}

我的 B 类看起来像这样:

class B {
    //instance variables
    parentClass;
    variable2;

    //instance methods
    instanceFunction(classA, other parameters) {
        parentClass = classA;
    }

    function1() {
        parentClass.setVariable1(someValue);
    }

    function2() {
        variable2 = parentClass.getVariable2();
    }
}

还有什么其他方法可以在 B 类中使用 A 类中的变量?

如果代码是 C++ 或 Java,假设所有变量都是私有的,所有方法和函数都是公共的。还假设所有变量都通过引用或指针传递。

编辑:

首先,感谢所有回复!

一些澄清:

我问这个问题的原因是我已经用 C++ 和 Python 完成了大量的 Qt 编程。在 Qt 中,有信号和槽。这让内部对象告诉外部对象做某事。例如,我有一个对象 A,里面有对象 B 和 C。对象 B 发生了一些变化,B 需要让 A 和 C 知道。所以B会发出一个信号。 A 会捕捉到这个信号并做它需要做的事情。然后,A 也会让 C 知道 B 发出了这个信号。这样 C 就可以做它需要做的事情了。

我之所以问这个问题是因为我想知道如何在不使用 Qt 库的情况下完成我所描述的事情。

另外,我们假设 B “不是” A,所以我不能/不想使用继承。

【问题讨论】:

  • 我认为这是一个非常糟糕的主意。
  • 您是否要求使用 Java、Python 或 C++ 编写答案?删除您不要求答案包含的语言。如果您正在寻找一种设计模式,您可能还需要添加该标签。

标签: java c++ python


【解决方案1】:

我不太清楚这个叫什么名字……

我在遵循您的伪代码时遇到问题,但您可以通过以下方式完成您正在寻找的内容:

  • Inheritance,它允许派生类从基类(静态或实例变量)访问受保护的变量
  • Friend functions (C++)(允许函数访问类上的私有实例变量)
  • Dependency Injection (但可能只有当您的要求比您在问题中实际陈述的要求更复杂时。在这种超级简单的情况下,当实例传递给函数时,您只需访问公共属性或字段 -您可能必须通过公共 getter/setter 访问它们,因为您希望变量是私有的)

编辑:

在您进行编辑后,很明显您需要the Observer Design Pattern。这允许您将响应状态更改的代码与指示状态更改的代码解耦。

这种模式不是关于访问变量(就像我的第一个链接那样),而是关于响应事件(或“状态转换”,如果你认为你的类是 Finite State Machine)。

【讨论】:

    【解决方案2】:

    鉴于您所做的编辑;使用boost::signals 或线程安全信号2(也在 boost 中)实现 sig/slot 机制可能是切实可行的。这意味着您正在寻找类似于 Qt 的 sigslot 机制的行为。还有很多替代方案,看SO问题here

    【讨论】:

    【解决方案3】:

    显式传递this(或者可能是this 周围的代理)几乎是唯一的(无论如何,理智的)方法,假设它们需要是单独的对象。对象不能也不应该需要知道其引用的数量和位置。即使您可以获得对自身的所有引用的列表,该列表也很容易包含局部变量、集合中的项目、可能的 A 的几个实例等 - 它应该如何知道选择哪一个作为其父级?

    如果 B 实际上是 "is an" A,则应该将其设为子类。

    【讨论】:

      【解决方案4】:

      还有哪些其他方法可以使用 A 类中的变量 B班里面?

      由于您的变量不是 static,它们是 instance 变量,因此 variable1variable2 仅在 A 的特定实例的上下文中有意义 - 所以需要对该实例的引用,无论您如何塑造它。

      例如Java中的内部类可以直接使用封闭外部类的变量,但实际上这只是编译器维护的一种假象,而在字节码中,内部类实际上保留了对外部类实例的引用.

      【讨论】:

      • 如果 B 是 A 的内部类,这意味着 B 实际上是在 A 内部声明的,对吗?在我的示例中,B 没有在 A 中声明。它是单独声明的。
      • @Di Zou:是的。这只是一个示例,说明实例变量总是通过对该实例的引用进行访问,即使该引用被隐藏。
      【解决方案5】:

      在 C++ 中,有一个友元类的概念:一个类A 可以声明另一个类B 作为它的友元,这使B 可以访问其私有变量A。只需在A 内写上friend class B;。 (正如@delnan 提醒我们的那样,您仍然需要手动为B 提供对A 的引用。)

      在 Java 中,如果您在 A 中声明 BB 将成为一个内部类。内部类只能从外部类的实例中实例化,内部类的实例会与外部类的对应实例绑定,并且可以访问其私有变量。

      (不过,我同意@mellamokb:这可能是个坏主意,因为它在两个类之间创建了非常紧密的耦合。您可能需要重新考虑您的类结构。您到底想用它做什么?)

      【讨论】:

      • 但是(编辑:friend)并没有神奇地给它一个对该类的某个实例的引用。根据BA 的需求,这只是规避封装所必需的一个实现细节。
      • @delnan:是的;现在提到它。
      • 是的,我同意这是非常糟糕的做法。我进行了编辑以尝试澄清我在寻找什么。现在,我没有正在处理的特定代码需要执行此操作,但我之前遇到过类似的情况,我想找出一种更好的方法来执行此操作。回调会是另一种方式吗?
      【解决方案6】:

      为了减少对象之间的耦合,你不应该让 B 引用 A - 你应该给它一个由 A 实现的接口的引用。区别是微妙的,但它确实让你思考什么动作或数据确实需要跨接口边界共享。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-05-26
        • 2011-10-30
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多