【问题标题】:is it safe to assign a stl container?分配一个stl容器是否安全?
【发布时间】:2012-06-20 16:11:19
【问题描述】:

例如:

set<int> s1;
set<int> s2;
s1.insert(1);
s2.insert(2);
s1 = s2;

安全吗?如果是这样,旧元素(以及它们发生的记忆)是从哪里来的?

【问题讨论】:

  • 这是使用类和运算符重载的好处。您可以处理这些事情,而无需用户担心。

标签: c++ stl variable-assignment


【解决方案1】:

是的,完成这项任务是安全的。它调用复制构造函数或赋值运算符,并删除 s1 中的旧元素并替换为 s2 的元素。

[注意:如果存在任何潜在问题,则复制构造函数和赋值将被禁止,例如fstream、ofstream、ifstream。]

【讨论】:

    【解决方案2】:

    是的。 旧元素将以通常的方式销毁并释放任何内存。 (当然,如果你在容器中存储指针,它只会破坏指针,而不会释放它指向的东西)

    【讨论】:

    • Afaik 这实际上是错误的。 s1 = s2 只复制 s2 中的元素并将它们放在 s1 中。两个对象只有在到达块的末尾时才会被销毁。
    • @LukasSchmelzeisen,您要复制到的集合中的旧元素。
    • 要清楚,我的意思是 s1 中的旧元素将被“破坏”,并且容器使用的任何内存都将在 s2 时被释放。对象 s1 和 s2 当然会在块的末尾被删除。
    【解决方案3】:

    是的,您的示例是安全的。但请注意:您没有将 s2 分配给 s1,而是将 s2 复制到 s1。欲了解更多信息,请参阅:set::operator=

    【讨论】:

    • 那个操作符不是常说的赋值操作符吗?
    • @Flexo 称为复制赋值运算符
    • @CaptainObvlious 这不是C++-FAQ-lite 所说的。
    • @flexo 但它是 C++ 语言标准所称的。
    • @flexo:这不是 赋值运算符,因为还有 compound 赋值运算符(+= 等),并且从 2011 年开始, 移动赋值运算符。
    【解决方案4】:

    作业是安全的。

    赋值运算符将通过调用它们的析构函数来销毁最初包含在 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 超出范围时清除。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-06-07
      • 1970-01-01
      • 2011-06-17
      • 1970-01-01
      • 2012-09-23
      • 1970-01-01
      相关资源
      最近更新 更多