代码之家  ›  专栏  ›  技术社区  ›  Uhall

为什么在标准容器中使用std::auto_ptr<>是错误的?

  •  201
  • Uhall  · 技术社区  · 16 年前

    为什么用错了 std::auto_ptr<> 用标准容器?

    6 回复  |  直到 7 年前
        1
  •  123
  •   community wiki 6 revs, 5 users 80% Kevin    11 年前

    C++标准称STL元素必须是“复制可构造”和“可赋值”。换句话说,一个元素必须能够被分配或复制,并且这两个元素在逻辑上是独立的。 std::auto_ptr 不满足此要求。

    以该代码为例:

    class X
    {
    };
    
    std::vector<std::auto_ptr<X> > vecX;
    vecX.push_back(new X);
    
    std::auto_ptr<X> pX = vecX[0];  // vecX[0] is assigned NULL.
    

    为了克服这个限制,您应该使用 std::unique_ptr , std::shared_ptr std::weak_ptr 如果没有C++ 11,智能指针或Boost等价物。 Here is the boost library documentation for these smart pointers.

        2
  •  65
  •   Frank Krueger    14 年前

    这个 拷贝语义 属于 auto_ptr 与容器不兼容。

    具体来说,复制一个 自动PTR 对于另一个对象,不会创建两个相等的对象,因为其中一个对象已经失去了指针的所有权。

    更具体地说,复制 自动PTR 使其中一个副本释放指针。容器中还保留哪些未定义。因此,如果存储 auto_ptrs 在容器中。

        3
  •  38
  •   Aakash Goel    14 年前

    关于这一主题的两篇非常优秀的文章:

        4
  •  17
  •   Aakash Goel    14 年前

    STL容器需要能够复制存储在其中的项目,并且设计为期望原始和副本是等效的。自动指针对象有一个完全不同的约定,通过复制可以创建所有权转移。这意味着,根据使用情况,auto-ptr的容器将表现出奇怪的行为。

    详细描述了有效STL(Scott Meyers)项目8中可能出错的内容,以及在有效的C++(Scott Meyers)项目13中不太详细的描述。

        5
  •  12
  •   Dustin Getz sunsations    16 年前

    STL容器存储所包含项目的副本。复制自动指针时,会将旧指针设置为空。许多容器方法都被这种行为破坏了。

        6
  •  4
  •   Alex Bitek    10 年前

    C++ 03标准(ISO-IEC 1488—2003) 如第20.4.5条第3段所述:

    […] [ 注:[…] auto-ptr不符合标准库的可复制构造和可分配要求 容器元素,从而实例化标准库容器 使用自动指针会导致未定义的行为。结束笔记 ]

    C++ 11标准(ISO-IEC 1488—2011) 如附录D.10.1第3段所述:

    […] 注:…]auto-ptr实例满足 可移动、可移动、可分配,但不符合要求 具有可复制构造性和可复制可分配性。“尾注”]

    C++ 14标准(ISO-IEC 1488—2014) 见附录C.4.2 附录D:兼容性特征:

    变化 :类模板auto-ptr、一元函数和二进制函数、函数模板random-shuffle和 函数模板(及其返回类型)ptr_fun、mem_fun, 未定义mem_fun_ref、bind1st和bind2nd。
    理论基础 :被新功能取代。
    对原始特征的影响 使用这些类模板和函数模板的有效C++ 2014代码可能无法在此编译。 国际标准。

    推荐文章