【问题标题】:When object variable is reassigned in C++, what happens to the original object?当在 C++ 中重新分配对象变量时,原始对象会发生什么?
【发布时间】:2015-02-14 03:45:52
【问题描述】:

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

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

【问题讨论】:

  • 通常,所发生的只是原始对象被修改了。

标签: c++ memory memory-management stack


【解决方案1】:

发生的情况是调用了类的赋值运算符。在大多数情况下,这只意味着旧对象的内容会使用新对象的值进行更新。所以如果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;
    }

对于具有动态内容的类,需要做更多的工作,但结果通常是相同的。由于赋值运算符可以被覆盖,理论上任何事情都可能发生,但这是我们所期望的。

【讨论】:

    【解决方案2】:

    实际上,对象没有任何反应:你还在使用它

    赋值不会用不同的对象替换整个对象:它调用原始对象的赋值运算符,允许对象使它看起来像新的东西,即使它不是。

    例如:

    int x = 1;
    x = 2;
    

    您在这里只声明了 一个 对象,即使它的值发生了变化。

    当然,即使在这个简单的 sn-p 中,也确实有多个对象在起作用——12 都是整数文字和临时对象。但是,您问的不是这些。它们的值被复制到x

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

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

    【讨论】:

      【解决方案3】:

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

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

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2016-04-29
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-07-03
        • 2012-09-08
        相关资源
        最近更新 更多