То, что вы неправильно понимаете, заключается в том, что (а) вы не можете передавать вещи по ссылке в Objective-C, и (б), даже если бы вы могли, это вам не поможет.
Objective-C позволяет передавать вещи только по значению. Иногда, как в случае объектов или указателей, передаваемое вами значение является самой ссылкой, но оно обрабатывается как значение. Прозрачные ссылки в стиле C ++ не существуют.
Но предположим, что они у нас были. Как это поможет в этом случае? Переменная экземпляра aNumber
по-прежнему имеет тип int*
; когда вы присваиваете ему (как в fred.aNumber = bob.aNumber
), вы должны создать копию. На данный момент не имеет значения, что было передано по ссылке, и не имеет значения, что вещи являются переменными экземпляра. Ваш код фактически такой же, как
int* bobNumber;
int* fredNumber;
bobNumber = malloc(sizeof(int));
*bobNumber = 5;
fredNumber = bobNumber;
Здесь bobNumber
и fredNumber
- это разные переменные & mdash; они имеют разные имена, живут в разных местах в памяти и т. Д. & Mdash; имеют одинаковое значение. Теперь значение, которое они имеют, является ссылкой на другое место в памяти, поэтому они являются эквивалентными ссылками. Однако что произойдет, если мы изменим один из них?
free(fredNumber);
fredNumber = malloc(sizeof(int));
*fredNumber = 7;
Поскольку аргументы функции передаются по значению, free
не может ничего сделать с fredNumber
; он может работать только со значением fredNumber
, освобождая ссылочную память. Поскольку это то же самое, что и значение bobNumber
, мы видим этот эффект, если пытаемся разыменовать bobNumber
. Далее мы присваиваем значение fredNumber
. Поскольку fredNumber
и bobNumber
живут в разных местах памяти, это назначение, естественно, ничего не делает с bobNumber
. На этом этапе fredNumber != bobNumber
, поэтому, естественно, когда мы присваиваем 7
*fredNumber
, ничего не происходит с *bobNumber
(что в любом случае недопустимо, только что было free
d).
Обратите внимание, что ваш комментарий о том, чтобы "заставить его работать как в C ++", странный; C ++, как я уже сказал, тоже не работает таким образом. Если вы действительно хотите, чтобы это работало в C ++, вам понадобится ссылочная переменная экземпляра
class ClassTwo {
public:
int*& aNumber;
ClassTwo(int*& an) : aNumber(an) { }
};
Обратите внимание, что an
необходимо передать по ссылке; Изначально я пытался сделать это без этого, а затем в конструкторе была создана копия, которая вызвала тот же старый набор проблем.
Теперь, независимо от того, передадим ли мы bob
по ссылке, он все равно будет иметь такую же ссылку aNumber
, поэтому мы можем построить что-то вроде
int* shared;
ClassTwo bob(shared);
bob.aNumber = new int(5);
ClassTwo fred(bob.aNumber);
delete fred.aNumber;
fred.aNumber = new int(7);
И все будет работать так, как вы ожидаете. Тем не менее, это может быть не очень хорошая идея. Обратите внимание, что по одной причине ссылки на переменные shared
должны иметь возможность ссылаться на что-либо. И это может вызвать проблемы: если ссылка на объект выходит из области видимости, поведение ссылки не определено.