@ user657267是对的,但让我详细说明一点。
abc,在main中声明为abc *a1 ;
,是一个像其他任何变量(比如int)一样的变量。它定义了一个内存位置,可能是4个字节,恰好位于函数main的堆栈中。该内存适用于在这种情况下恰好是地址的一些数据。
与任何变量一样,变量存储的内存位置其数据也具有地址。这可能让人第一眼就感到困惑,但它并没有什么魔力 - 地址和其他值一样,并且可以存储在变量中,变量占据某处具有自己地址的某个内存。
将a1的地址传递给一个函数是正确的,该函数将更改变量所保存的数据。正确地,当您将其地址传递给函数getdata(&a1);
时,将运算符&应用于变量名称。
getdata()现在知道a1保存其数据的地方,即在复制到形式参数“input”的地址处。当getdata想要更改该数据时,需要写入该位置。这是使用运算符*,即解引用运算符完成的。
现在a1中的数据恰好是abc对象的一个(当前可能是无效的)地址。要分配给a1的合适数据将是abc对象的地址。例如,使用abc *ap = new abc;
创建的新abc对象的指针ap对于此类赋值非常有用。我们可以在getdata中访问a1,因为我们碰巧有输入地址。与通过地址进行任何分配一样,我们需要使用解引用运算符*来访问位置,其中“输入”中的地址正在描述。 (据我们所知,该位置是a1数据所在的位置)。
input = new abc*;
现在做什么?右侧“new abc *”在堆上创建一个可容纳地址的位置,可能为4个字节。它的类型是“abc *”。
运算符“new”返回新创建的对象的地址(即,可以容纳地址的abc的4个字节的地址),并将该地址分配给输入。 Oy vey - 我们已经失去了main的a1存储其数据的信息!这是“投入”持续到现在的价值。 “输入”现在指向一个不同的,完全有效的内存位置,它可以保存abc的地址。 *input = ap ;
将在getdata()开头创建的abc的地址写入该内存位置。 Bummer,数据主的a1所持有的根本不变。因为没有分配给它,所以它包含的随机字节很可能仍然是一个完全无效的地址。
因此,虽然*input = ap ;
是完全正常的,但它会在错误的位置更改数据。省略覆盖输入所持有的a1数据的完全有效位置,并且一切都将工作。 a1的内容将被getdata()改变,getdata()将把一个新创建的abc对象的地址写入它,以便取消引用指针,例如通过a1->getX()
,将是一个有效的操作。
为了避免意外覆盖只读参数,可以声明它们为const。在这种情况下,getdata(abc **const input)
将表明您不想更改“输入”包含的值。 (但您仍然可以使用使用该值访问a1的数据!)因此,分配input = new abc*;
会引发编译时错误。