Есть ли способ изменить внешний объект изнутри функции

Можно ли определить функцию, которая заставит аргумент ссылаться на другой (уже существующий) объект после его возвращения без использования указателей и т. Д.? Опять же, это не может просто изменить существующий объект с помощью конструктора копирования или оператора присваивания или чего-либо еще. Внешний объект будет ссылаться на другой блок памяти, когда функция вернется.

Например:

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
Другие вопросы по тегам