关于c ++:析构函数调用(堆栈)变量之间的赋值?

Destructor called on assignment between (stack) variables?

1
2
3
matrix m1(5,5);
matrix m2(5,5);
m1 = matrix(m2);

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


不,在执行分配之前,分配操作员需要处理释放m1可能持有的任何资源。只有当m1即将超出作用域时,才会调用析构函数。


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


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

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

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

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

例如,boost包含专门用于保存指针的专用容器类。Boost还有一个共享指针类,可以由普通容器保存。

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


我认为这取决于矩阵是否正确实现了析构函数以及如何实现赋值运算符。如果matrix有一个工作析构函数,matrix使用"赋值交换"(类似于copy-swap惯用法),那么yes m1应该被正确释放。

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