2

This is more of a general programming question so the code examples I give will just be pseudo-code. I program in C++, Java, and Python so the pseudo-code is a mix of those. I am not too sure what the name of this is called so if you could give me a name for this, I can Google for more information about it I would greatly appreciate it.

Let's say I have a class called A. In this class, I create an instance of a class called 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;
    }
}

In class B, I want to make changes to or make use of instance variables in class A. I can do this by passing a reference to A into B. So my A::function1 would look like this:

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

and my class B would look like this:

class B {
    //instance variables
    parentClass;
    variable2;

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

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

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

What other ways are there to have use of the variables in class A inside of class B?

If the code was C++ or Java, assume all variables are private and all methods and functions are public. Also assume all variables are passed by references or a pointers.

Edit:

First, thanks for all the responses!

Some clarification:

The reason I am asking this question is I have done a good amount of Qt programming in C++ and Python. In Qt, there are signals and slots. This lets inner objects tell the outer object to do something. For example I have an object A with objects B and C inside of it. Some change happens to object B and B needs to let A and C know. So B will emit a signal. A will catch this signal and do what it needs to do. Then, A will also let C know that B emitted this signal. This way C can do what it needs to do.

The reason I asked my question is because I was wondering how I can do something like I described without using the Qt libraries.

Also, let's assume B "is not" an A so I can't/don't want to use inheritance.

Di Zou
  • 4,469
  • 13
  • 59
  • 88

6 Answers6

2

I am not too sure what the name of this is called...

I am having trouble following your pseudo-code, but you might be able to accomplish what you're looking for via:

  • Inheritance, which allows derived classes to access protected variables from a base class (static or instance variables)
  • Friend functions (C++) (which allows functions to have access to private instance variables on a class)
  • Dependency Injection (But probably only if you have more complex requirements than you're actually stating in your question. In this super-simple case, you'd just be accessing public properties or fields when an instance is passed in to a function - you might have to access them through a public getter/setter, since you want the variables to be private)

Edit:

After your edits, it is pretty clear that you want the Observer Design Pattern. This allows you to decouple the code that responds to a state change from the code that signals the state change.

That pattern is less about access to variables (as my first links were about), than it is about responding to events (or "state transitions", if you think about your class as a Finite State Machine).

Merlyn Morgan-Graham
  • 58,163
  • 16
  • 128
  • 183
2

Given the edit you made; It may be practical to implement a sig/slot mechanism using boost::signals, or the threadsafe signals2 (also in boost). This is implying that you are looking for a behaviour similar to Qt's sigslot mechanism. There are also many alternatives, look at the SO question here.

Community
  • 1
  • 1
Seb Holzapfel
  • 3,793
  • 1
  • 19
  • 22
  • Thanks! That is probably closes to what I am looking for. I think I have found the name for what I am describing: http://en.wikipedia.org/wiki/Observer_pattern and http://en.wikipedia.org/wiki/Publish/subscribe – Di Zou Aug 01 '11 at 19:56
  • Yep, that's it. Sigslot at it's most basic level is just those patterns condensed in an easily-implemented way. – Seb Holzapfel Aug 01 '11 at 20:05
0

In C++, there is a concept of friend classes: a class A can declare another class B to be its friend, something which gives B access to the private variables of A. Simply write friend class B; inside of A. (As @delnan reminds us, you still need to manually give B a reference to A.)

In Java, if you declare B inside of A, B will become an inner class. Inner classes can only be instantiated from an instance of the outer class, and the instance of the inner class will be tied to the corresponding instance of the outer class, and may access its private variables.

(I agree with @mellamokb, though: This is probably a bad idea, as it creates very tight coupling between the two classes. You might want to rethink your class structure. What exactly are you trying to use this for?)

Aasmund Eldhuset
  • 37,289
  • 4
  • 68
  • 81
  • 1
    But that (edit: `friend`) doesn't magically give it a reference to some instance of that class. It's only a implementation detail that may be necessary to circumvent encapsulation depending on what `B` needs of `A`. –  Aug 01 '11 at 19:02
  • @delnan: True; mentioning it now. – Aasmund Eldhuset Aug 01 '11 at 19:24
  • Yes I agree this is pretty bad practice. I made an edit to try and clarify what I'm looking for. Right now, I don't have a specific piece of code I am working on that I need to do this, but I have run into similar situations before, and I want to figure out a better way of doing this. Would callbacks be another way of doing this? – Di Zou Aug 01 '11 at 19:29
0

Explicitly passing this (or perhaps a proxy around this) is pretty much the only (sane, anyway) way to do it, assuming they need to be seperate objects. An object can't and shouldn't need to know number and location of its references. And even if you could get a list of all references to itself, that list could easily contain local variables, items in collections, potentially several instances of A, etc. - how is it supposed to know which one to chose as its parent?

If a B actually "is an" A, you should just make it a subclass.

0

What other ways are there to have use of the variables in class A inside of class B?

Since your variables are not static, they are instance variables, so variable1 and variable2 are only meaningful in the context of a specific instance of A - so there needs to be a reference to that instance, not matter how you shape it.

For example, inner classes in Java can use variables of the enclosing outer class directly, but in reality this is just an illusion maintained by the compiler, and in the bytecode, the inner class actually keeps a reference to the outer class instance.

Michael Borgwardt
  • 342,105
  • 78
  • 482
  • 720
  • If B was an inner class of A, it would mean B is actually declared inside of A correct? In my example, B is not declared inside A. It is declared separately. – Di Zou Aug 01 '11 at 19:32
  • @Di Zou: Yes. It was just an example to illustrate that instance variables are *always* accessed through a reference to that instance, even if that reference is hidden. – Michael Borgwardt Aug 01 '11 at 19:43
0

To reduce coupling between the objects, you shouldn't let B have a reference to A - you should give it a reference to an interface implemented by A. The difference is subtle, but it really makes you think about what actions or data really need to be shared across the interface boundary.

Mark Ransom
  • 299,747
  • 42
  • 398
  • 622