你能用C ++破坏和重建一个向量的元素吗?

问题描述 投票:0回答:2

从外部破坏和构造向量元素是否合法?假设您将一组元素保留在您开始构建的状态中,当然?并假设不做任何明显愚蠢的事情,比如在相同的元素上调用析构函数两次,或类似的。

抛开异常,我想象的是以下内容:

int main ()
{
  std::vector<std::string> v (10, "Hello");

  v [2].std::string::~string ();

  new (&v [2]) std::string ("World");
}

或者这样的事情会是UB吗?其他标准容器呢?

c++ constructor destructor stdvector
2个回答
4
投票

这是完全有效的,就像你总是可以显式地调用任何对象的析构函数一样。但是,它可能是愚蠢的。在摧毁和复活元素之间,向量处于无法被破坏的状态。如果由于某种原因调用了析构函数,则会获得UB。这特别危险,因为你可能不会一个接一个地做这两个步骤。

现在,你不只是为了好玩而这样做。如果你想要,例如要擦除一个元素,你可以创建一个临时的,与元素交换然后销毁临时元素。这样,你就不会有这个窗口,你不能破坏矢量。此外,这种方法甚至适用于像std::string元素这样的非常重要的情况,也适用于更复杂的矢量元素。


1
投票

你可以这样做,但是矢量中的插槽在破坏和重建之间是无效的。如果由于某种原因(可能是异常),在重构之前调用向量的DTOR,接着会出现未定义的行为。

以下是一个更安全的替代方案。任何合理质量的std :: string实现都将构造一个带有“World”的新std :: string,然后使用rvalue-assignment运算符(move-semantics)将其放入向量槽。执行此任务期间没有任何周期受到伤害。

#include <string>
#include <iostream>

int main()
{ 
    v[2] ="World";
    std::cout << v[2] << std::endl;
    return 0;
}
© www.soinside.com 2019 - 2024. All rights reserved.