【发布时间】:2012-04-14 02:32:26
【问题描述】:
matrix m1(5,5);
matrix m2(5,5);
m1 = matrix(m2);
对于上面的代码(对于任意类,矩阵),当 m2 的信息被复制到它时,是否会为与 m1 关联的信息调用析构函数?
【问题讨论】:
-
这正是调试器所擅长的。
-
或者简单的调试输出。
标签: c++ destructor lifetime
matrix m1(5,5);
matrix m2(5,5);
m1 = matrix(m2);
对于上面的代码(对于任意类,矩阵),当 m2 的信息被复制到它时,是否会为与 m1 关联的信息调用析构函数?
【问题讨论】:
标签: c++ destructor lifetime
不,赋值运算符需要在执行赋值之前释放m1 可能持有的任何资源。只有当m1 即将超出范围时才会调用析构函数。
【讨论】:
不,一旦在堆栈上分配的对象被构造,它就不会被解构,直到它超出范围或你显式调用它的析构函数(你可能永远不应该这样做)。所以在这种情况下,如果矩阵定义了一个重载的 operator=(const matrix& rhs) 成员函数,则调用 operator=() 并将 rhs 复制到 m1 中。否则,使用默认赋值,它简单地将所有成员变量从临时 matrix(m2) 对象复制到 m1,覆盖这些变量的先前值。
【讨论】:
我认为这取决于矩阵是否正确实现了析构函数以及赋值运算符是如何实现的。如果矩阵有一个有效的析构函数并且矩阵使用“assignment-swap”(类似于copy-swap idiom),那么是的,应该正确释放M1。
此外,在调用 m1 = m2 时,您实际上并不需要 Matrix(m2)。这只是调用复制构造函数,然后将临时副本分配给 m1。因此,无用的工作正在发生。
【讨论】:
这个矩阵是什么容器?如果是价值观,那就没有问题了。如果是智能指针,那就没有问题了。
但是如果涉及到普通的指针呢?然后完全取决于matrix::operator=(const matrix&)的实现。如果需要在那里调用任何析构函数,它应该调用它们。这不是靠魔法发生的,你必须考虑这些事情。
一般来说,使用普通容器类来保存普通指针是个坏主意。如果不调用析构函数,则会泄漏内存。如果调用析构函数,如果通过另一个指针访问同一个对象,则会崩溃。 (想象一下,如果你有两个矩阵都包含指向同一个对象的指针。)
因为使用普通容器类来处理普通指针的容器既困难又危险。为此应使用专门的容器或专门的指针。
例如,Boost 包含 specialized container classes 专门用于保存指针。 Boost 还有一个shared pointer class,普通容器可以装。
您只需要决定应该发生什么。如果你做a=b;,a 和b 应该持有指向相同底层对象的指针吗?还是应该为a 创建新对象以指向内部?
【讨论】: