3

I got two classes.

  • busiObj(created from ancient flat files)
  • key(provides means to tell busiObjs apart)

key has a c'tor that takes a busiObj

public key(busiObj foo)
{
    bar = foo.someThing;
    [...]
}

I want to create the key in the c'tor of the busiObj

public busiObj(...)
{
    myKey = new key(this);
    [...]
}

However: Why on earth does it work?
I firmly expected the compiler to throw something like:
"You cannot reference an object that is currently being made, duh".

So: How is it that I can reference an object while it is still being constructed?

Mark
  • 373
  • 5
  • 13
  • 2
    The object might not be finished being constructed, but we know where it will be (in memory) when it is, hence we can get a reference to that location. – George Duckett Jul 01 '14 at 07:30
  • @GeorgeDuckett then is it safe to do this call, given that I initialized all parts of myObj that the c'tor of key uses? Also: Is this bad practice (it somehow feels so)? – Mark Jul 01 '14 at 07:33

2 Answers2

3

So: How is it that I can reference an object while it is still being constructed?

Presumably Because it's useful (though in a dangerous way) for exactly the scenario you describe, so the language designers decided to allow it.

Technically, it's not a problem at all: while the object is being constructed, its memory must already be allocated, so you can certainly have a reference to it.

Michael Borgwardt
  • 51,037
  • 13
  • 124
  • 176
  • Just as @George Duckett also lines out. It feels wrong though. – Mark Jul 01 '14 at 07:35
  • 4
    @Mark: It's safe to do inasmuch as there is no undefined behaviour; the worst you can encounter (if you make a mistake) is object states (mostly null references) that are not possible according to your class contract. It's not a good practice because in maintaining that code, it's easy to lose track of the fact that you're handling a partially initialized object and introduce weird bugs. – Michael Borgwardt Jul 01 '14 at 07:46
  • [Instantiate an object without a constructor](http://stackoverflow.com/questions/296584/c-create-object-instance-without-invoking-constructor) is intriguing. It means an object exists before the constructor is called. – radarbob Jul 04 '14 at 01:28
1

Why this happens is because this is a reference to the memory area that your object is currently occupying. Since instructions in the code are executed sequentially, you already have your object in some state that's being referenced when you get to the point of calling the key() method.

Although this is possible, the entire approach is wrong. The methods inside an object should only change the state of the instance, not the state of other instances of that object. Your example works because it roughly translates into the code below at runtime:

public busiObj() { 
    myKey = new key();
    [...]
}

public key()
{
    bar = foo.someThing;
    [... use "this" here to reference your object internally ...]
    [... other stuff here ...]
}
Thyamarkos
  • 378
  • 1
  • 4
  • **...not the state of other instances of that object** where am I doing that? I am not changing one busiObj from another. – Mark Jul 01 '14 at 08:37
  • In your implementation the **key()** method gets a *busiObj* object as a parameter - but you're under no obligation to send the current instance to the method. Assuming you work on the **foo** object that you get, if that object is not **this** then you will essentially work in your method with another object. Since you are sending the **this** reference from the constructor, the interpreter takes care of translating the reference to your current object in **key()**, but this will not alwais be the case. – Thyamarkos Jul 01 '14 at 08:40
  • ahh, that's what you mean. I am actually reading already initialized properties from the passed, half-finished busiObj, not manipulating its state though. – Mark Jul 01 '14 at 08:43