【问题标题】:Destructor called on assignment between (stack) variables?析构函数调用(堆栈)变量之间的赋值?
【发布时间】:2012-04-14 02:32:26
【问题描述】:
matrix m1(5,5); 
matrix m2(5,5); 
m1 = matrix(m2); 

对于上面的代码(对于任意类,矩阵),当 m2 的信息被复制到它时,是否会为与 m1 关联的信息调用析构函数?

【问题讨论】:

  • 这正是调试器所擅长的。
  • 或者简单的调试输出。

标签: c++ destructor lifetime


【解决方案1】:

不,赋值运算符需要在执行赋值之前释放m1 可能持有的任何资源。只有当m1 即将超出范围时才会调用析构函数。

【讨论】:

    【解决方案2】:

    不,一旦在堆栈上分配的对象被构​​造,它就不会被解构,直到它超出范围或你显式调用它的析构函数(你可能永远不应该这样做)。所以在这种情况下,如果矩阵定义了一个重载的 operator=(const matrix& rhs) 成员函数,则调用 operator=() 并将 rhs 复制到 m1 中。否则,使用默认赋值,它简单地将所有成员变量从临时 matrix(m2) 对象复制到 m1,覆盖这些变量的先前值。

    【讨论】:

      【解决方案3】:

      我认为这取决于矩阵是否正确实现了析构函数以及赋值运算符是如何实现的。如果矩阵有一个有效的析构函数并且矩阵使用“assignment-swap”(类似于copy-swap idiom),那么是的,应该正确释放M1。

      此外,在调用 m1 = m2 时,您实际上并不需要 Matrix(m2)。这只是调用复制构造函数,然后将临时副本分配给 m1。因此,无用的工作正在发生。

      【讨论】:

      • 可以调用存储m1之前值的临时对象的析构函数,但不应该调用m1的析构函数。
      • 如上所述,如果存在有效的析构函数和复制构造函数,则赋值运算符将能够释放 m1 的内容。问题是 m1 会在分配时被释放,而不是在离开范围时释放......见:stackoverflow.com/questions/276173/…
      【解决方案4】:

      这个矩阵是什么容器?如果是价值观,那就没有问题了。如果是智能指针,那就没有问题了。

      但是如果涉及到普通的指针呢?然后完全取决于matrix::operator=(const matrix&)的实现。如果需要在那里调用任何析构函数,它应该调用它们。这不是靠魔法发生的,你必须考虑这些事情。

      一般来说,使用普通容器类来保存普通指针是个坏主意。如果不调用析构函数,则会泄漏内存。如果调用析构函数,如果通过另一个指针访问同一个对象,则会崩溃。 (想象一下,如果你有两个矩阵都包含指向同一个对象的指针。)

      因为使用普通容器类来处理普通指针的容器既困难又危险。为此应使用专门的容器或专门的指针。

      例如,Boost 包含 specialized container classes 专门用于保存指针。 Boost 还有一个shared pointer class,普通容器可以装。

      您只需要决定应该发生什么。如果你做a=b;ab 应该持有指向相同底层对象的指针吗?还是应该为a 创建新对象以指向内部?

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2018-06-14
        • 2012-08-28
        • 2013-04-14
        • 2015-01-17
        • 2013-11-27
        • 2014-11-27
        • 1970-01-01
        相关资源
        最近更新 更多