What you are misunderstanding is that (a) you cannot pass things by reference in Objective-C, and (b) even if you could, it wouldn't help you here.
Objective-C only allows you to pass things by value. Sometimes, as in the case of objects or pointers, the value you are passing is itself a reference, but it's being treated as a value. C++-style transparent references don't exist.
But suppose that we had them. How would that help in this case? The aNumber
instance variable is still of type int*
; when you assign to it (as in fred.aNumber = bob.aNumber
), you must create a copy. At this point, it doesn't matter what was passed by reference, and nor does it matter that things are instance variables. Your code is effectively the same as
int* bobNumber;
int* fredNumber;
bobNumber = malloc(sizeof(int));
*bobNumber = 5;
fredNumber = bobNumber;
Here, bobNumber
and fredNumber
are different variables—they have different names, live at different locations in memory, etc.—that happen to have the same value. Now, the value they have is a reference to another location in memory, so they are equivalent references. However, what happens if we change one of them?
free(fredNumber);
fredNumber = malloc(sizeof(int));
*fredNumber = 7;
Since function arguments are passed by value, free
can't do anything to fredNumber
itself; it can only operate on fredNumber
's value, freeing the referenced memory. Since this is the same as bobNumber
's value, we see this effect if we try to dereference bobNumber
. Next, we assign a value to fredNumber
. Since fredNumber
and bobNumber
live at different locations in memory, this assignment naturally does nothing to bobNumber
. At this point, fredNumber != bobNumber
, so naturally when we assign 7
to *fredNumber
, nothing happens to *bobNumber
(which is invalid anyway, having just been free
d).
Note that your comment about "making it work like C++ does" is strange; C++, like I said, doesn't work this way either. If you really wanted to make this work in C++, you would have to have a reference instance variable
class ClassTwo {
public:
int*& aNumber;
ClassTwo(int*& an) : aNumber(an) { }
};
Note that an
needs to be passed by reference; I originally tried to do it without that, and then a copy was created in the constructor, producing the same old set of problems.
Now, whether or not we pass bob
by reference, it will still have the same aNumber
reference, so we can construct something like
int* shared;
ClassTwo bob(shared);
bob.aNumber = new int(5);
ClassTwo fred(bob.aNumber);
delete fred.aNumber;
fred.aNumber = new int(7);
And everything will work like you expect. However, this may well not be a good idea. For one reason why, note the shared
variable—references need to be able to reference something. And this can produce problems: if the object being reference goes out of scope, the behavior of the reference is undefined.