在C ++中重新分配对象变量时,原始值会发生什么变化? 在下面的代码中,对象被创建到堆栈上并放在变量中。然后在堆栈上创建一个新对象并将其放在同一个变量中。原始对象会发生什么?在变量超出范围之前,它是否会保留在堆栈中?
void foo() {
ClassName variable(a, b); // variable created on the stack
variable = ClassName(c, d); // new value for variable created on stack
...
}
答案 0 :(得分:10)
发生的是调用类的赋值运算符。在大多数情况下,这意味着旧对象的内容使用新对象的值进行更新。如果ClassName
是:
struct ClassName
{
int a;
int b;
ClassName(int a, int b) : a(a), b(b) {}
};
在这种情况下,将调用默认赋值运算符,该运算符等效于:
ClassName& operator=(const ClassName& other)
{
a = other.a;
b = other.b;
return *this;
}
对于具有动态内容的类,可能会有更多事情要做,但结果通常是相同的。由于可以覆盖赋值运算符,理论上可以发生任何事情,但这正是我们所期望的。
答案 1 :(得分:4)
实际上,对象没有任何反应:你还在使用它!
赋值不会用不同的对象替换整个对象:它调用原始对象的赋值运算符,允许对象使其看起来像新的东西,即使它不是。
例如:
int x = 1;
x = 2;
您在此处仅声明了一个对象,即使其值已更改。
当然,即使是这个简单的片段,确实有多个对象在进行 - 1
和2
都是整数文字和临时对象。但是,您问的不是这些。它们的值被复制到x
。
同样,在您自己的代码中,您将临时ClassName(c, d)
的“值”复制到variable
,但variable
仍然是原始variable
。
临时ClassName(c, d)
超出了您使用它的行末尾的范围;用于表示它的字节(除非优化出来)可能会驻留在堆栈帧中,直到你离开函数范围,尽管你在法律上无法读取它们。
答案 2 :(得分:3)
从技术上讲,operator=
由分配的左侧部分调用,例如
variable.operator=(ClassName(c,d));
在您的情况下,如果您没有明确定义赋值运算符,编译器会为您生成一个默认运算符,它使用其各个成员的副本赋值运算符复制右侧。因此左侧(即您案件中的variable
)被修改,其个别成员是右侧临时成员的副本。