有没有办法从函数内部改变外部对象?

Is there any way to change an outside object from inside a function

本文关键字:改变 外部 对象 内部 函数 有没有      更新时间:2023-10-16

是否有可能定义一个函数,该函数将使参数在返回后引用另一个(已经存在的)对象,而不使用指针等?同样,这不能通过使用复制构造函数或赋值操作符或其他方法来改变现有对象。当函数返回时,外部对象将指向不同的内存块。

例如:

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);

在调用函数之前不对实参应用任何特殊操作符或函数。我不知道这是否可行,但如果可行的话,会让很多很酷的事情成为可能。如果不是,我也想知道为什么。

不能,因为somethingx是不同的对象。它们并不是指不同的对象。它们没有指向不同的物体。它们不同的对象。

要改变某物指向的位置,该物必须是指针。如果你有一个指针,你可以这样做:

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