Есть ли способ изменить внешний объект изнутри функции
Можно ли определить функцию, которая заставит аргумент ссылаться на другой (уже существующий) объект после его возвращения без использования указателей и т. Д.? Опять же, это не может просто изменить существующий объект с помощью конструктора копирования или оператора присваивания или чего-либо еще. Внешний объект будет ссылаться на другой блок памяти, когда функция вернется.
Например:
int x;
void change(int& blah) {
blah = x; // I don't want to change blah's value to x's value, I want to make blah refer to x outside the function
}
void main() {
int something = 0;
change(something);
assert(&x == &something);
}
Независимо от используемого метода, функция должна вызываться как
change(x);
Без применения какого-либо специального оператора или функции к аргументу перед вызовом функции. Я не знаю, возможно ли это, но это сделало бы очень крутые вещи возможными, если бы это было возможно. Если это не так, я также хотел бы знать, почему.
3 ответа
Нет потому что something
а также x
это разные объекты. Они не относятся к разным объектам. Они не указывают на разные объекты. Это разные объекты.
Чтобы изменить, где что-то указывает, что-то должно быть указателем. Если у вас есть указатель, вы можете сделать это:
int x;
void change(int*& p)
{
p = &x;
}
int main()
{
int something = 0;
int* pointer = &something; // pointer points to 'something'
change(pointer); // now pointer points to 'x'
assert(&x == pointer);
}
Нет точно не возможно. Обе регулярные переменные, как int x
и ссылки на переменные, такие как int &y(...)
и массивы не могут быть перезаписаны, то есть они всегда будут использовать / указывать на один и тот же кусок памяти.
Чтобы получить требуемую функциональность, вам действительно нужно использовать указатель или абстракцию указателей. В противном случае это невозможно.
В качестве попытки объяснения, здесь идет (не совсем правильно, и сильно упрощено, но достаточно хорошо, чтобы понять):
Когда вы объявляете переменную, как int x
вы действительно просите компилятор связать x
с определенной областью памяти. Так, например, предположим, x
связан с четырехбайтовым, начиная с 0x439FC2
, Поскольку компилятор знает, что x
всегда следует ссылаться на 0x439FC2
, чем любое использование x
действительно можно заменить, просматривая эти ячейки памяти и загружая их в регистры, помещая их в стек или что-то еще. В любом случае, конечным результатом является то, что имя переменной x
в значительной степени заменяется числом 0x439FC2
, Так что причина, по которой вы не можете двигаться x
в том, что вы не можете сделать так, чтобы этот адрес памяти ссылался на другое место в памяти.
Опять же, это объяснение упрощено и не совсем верно, но это "интуитивный" способ рассуждения об автоматически назначаемых переменных.
Вы хотите использовать ссылку на указатель:
void change(int &* blah, int * x){
blah = x;
}
int * num1;
int num2 = 2;
change( num1, &num2 ); //num1 now points to num2