【发布时间】:2012-06-20 16:11:19
【问题描述】:
例如:
set<int> s1;
set<int> s2;
s1.insert(1);
s2.insert(2);
s1 = s2;
安全吗?如果是这样,旧元素(以及它们发生的记忆)是从哪里来的?
【问题讨论】:
-
这是使用类和运算符重载的好处。您可以处理这些事情,而无需用户担心。
标签: c++ stl variable-assignment
例如:
set<int> s1;
set<int> s2;
s1.insert(1);
s2.insert(2);
s1 = s2;
安全吗?如果是这样,旧元素(以及它们发生的记忆)是从哪里来的?
【问题讨论】:
标签: c++ stl variable-assignment
是的,完成这项任务是安全的。它调用复制构造函数或赋值运算符,并删除 s1 中的旧元素并替换为 s2 的元素。
[注意:如果存在任何潜在问题,则复制构造函数和赋值将被禁止,例如fstream、ofstream、ifstream。]
【讨论】:
是的。 旧元素将以通常的方式销毁并释放任何内存。 (当然,如果你在容器中存储指针,它只会破坏指针,而不会释放它指向的东西)
【讨论】:
s1 = s2 只复制 s2 中的元素并将它们放在 s1 中。两个对象只有在到达块的末尾时才会被销毁。
是的,您的示例是安全的。但请注意:您没有将 s2 分配给 s1,而是将 s2 复制到 s1。欲了解更多信息,请参阅:set::operator=
【讨论】:
+= 等),并且从 2011 年开始, 移动赋值运算符。
作业是安全的。
赋值运算符将通过调用它们的析构函数来销毁最初包含在 s1 中的对象(在您的示例中,对于 int 来说这是一个微不足道的空操作)。该集合是否也释放内存,或者将其保留为未初始化的内存以供后续添加的元素使用,取决于实现。
s1 中的新对象将从 s2 中复制,这可能需要相当长的时间。如果您不想在分配后保留 s2,更好的方法可能是交换两个容器或使用 C++11 移动分配。
std::swap(s1, s2); // Backwards-compatible swap
s1 = std::move(s2); // C++11 rvalue move assignment
这两者很可能只是交换一个指针,将您要保留在 s1 中的内容和其余内容留在 s2 中,以便在 s2 超出范围时清除。
【讨论】: