How to create instance of class that get data from 2 another instance?

Ali Çehreli via Digitalmars-d-learn digitalmars-d-learn at puremagic.com
Sun Jan 4 16:08:14 PST 2015


On 01/04/2015 07:37 AM, Suliman wrote:

 > how to write code above without passing this as parameter...

For reference, here is your code:

   http://www.everfall.com/paste/id.php?a5pp73ns1e4k

There is nothing fundamentally wrong in a class constructor passing 
'this' to an object that it constructs:

class A
{
     B b;

     this() {
         b = new B(this);  // Makes its B
     }
}

However, keep in mind that 'this' is not an A until we leave the 
constructor. For that reason, the B's constructor must not use the A 
reference that it receives.

In that code, apparently A owns a B for its purposes. Presumably, that 
is why A's constructor is creating a B object. Commonly, it is either 
not the case or even if so, we want to provide a B from "above" so that 
A becomes testable. (Search for "parametrize from above" by "kevlin 
henney"; or search for "dependency injection".)

So, usually the following idiom is prefered:

class A
{
     B b;

     this(B b) {
         this.b = b;  // Takes its B as a parameter
     }
}

Well, it works fine until you need both of the objects to refer to each 
other:

class A
{
     B b;

     this(B b) {
         this.b = b;
     }
}

class B
{
     A a;

     this(A a) {
         this.a = a;
     }
}

It is impossible to construct two objects at the same, which refer to 
each other:

     auto a = new A(/* where is my B? */);  // Oops!
     auto b = new B(a);

So, A must not have an invariant that requires non-null B and that it 
must have a property to set the B later on:

     auto a = new A(null);
     // Here, A must be happy with null B
     auto b = new B(a);
     a.b = b;    // Finally, we have two happy objects

So, your code is just fine because there is no general solution anyway.

Ali



More information about the Digitalmars-d-learn mailing list