在C ++中重新分配对象变量时,原始对象会发生什么?

时间:2014-12-15 22:28:58

标签: c++ memory memory-management stack

在C ++中重新分配对象变量时,原始值会发生什么变化? 在下面的代码中,对象被创建到堆栈上并放在变量中。然后在堆栈上创建一个新对象并将其放在同一个变量中。原始对象会发生什么?在变量超出范围之前,它是否会保留在堆栈中?

void foo() {
    ClassName variable(a, b); // variable created on the stack
    variable = ClassName(c, d); // new value for variable created on stack
    ...
}

3 个答案:

答案 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;

您在此处仅声明了一个对象,即使其值已更改。

当然,即使是这个简单的片段,确实有多个对象在进行 - 12都是整数文字和临时对象。但是,您问的不是这些。它们的值被复制到x

同样,在您自己的代码中,您将临时ClassName(c, d)的“值”复制到variable,但variable仍然是原始variable

临时ClassName(c, d)超出了您使用它的行末尾的范围;用于表示它的字节(除非优化出来)可能会驻留在堆栈帧中,直到你离开函数范围,尽管你在法律上无法读取它们。

答案 2 :(得分:3)

从技术上讲,operator=由分配的左侧部分调用,例如

variable.operator=(ClassName(c,d));

在您的情况下,如果您没有明确定义赋值运算符,编译器会为您生成一个默认运算符,它使用其各个成员的副本赋值运算符复制右侧。因此左侧(即您案件中的variable)被修改,其个别成员是右侧临时成员的副本。

相关问题