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

什么时候使用std::auto_ptr而不是boost::shared_ptr?

  •  17
  • Alan  · 技术社区  · 15 年前

    我们已经开始使用 boost::shared_ptr 但是,在我们所有的代码中,我们在使用 std::auto_ptr 包括单件课程:

    template < typename TYPE >
    class SharedSingleton
    {
    public: 
        static TYPE& Instance()
        {
            if (_ptrInstance.get() == NULL)
                _ptrInstance.reset(new TYPE);
            return *_ptrInstance;
        }
    
    protected: 
        SharedSingleton() {};
    
    private:
        static std::auto_ptr < TYPE > _ptrInstance;
    };
    

    有人告诉我,这是一个很好的理由 shared_ptr 但是对于我的生活我不明白为什么?我知道 auto_ptr 最终会在下一个标准中被标记为贬值,所以我想 知道如何替换此实现 .

    此外,您是否有其他理由考虑使用 自动PTR 而不是 SelddPPTR ? 您是否看到将来有任何问题转移到共享资源?


    编辑:

    1. 所以在回答“我能安全地替换吗?” 自动PTR 具有 SelddPPTR 在上面的代码中,答案是“是”,不过我会对性能有一点影响。
    2. 什么时候? 自动PTR 最终被标记为已贬值,我们转移到 std::shared_ptr 我们需要彻底测试我们的代码,以确保遵守不同的所有权语义。
    3 回复  |  直到 15 年前
        1
  •  35
  •   Frerich Raabe    14 年前

    auto_ptr shared_ptr 解决完全不同的问题。一个不能取代另一个。

    自动PTR 是要实现的指针周围的瘦包装 RAII 语义,这样即使面对异常,资源也总是被释放。 自动PTR 根本不执行任何引用计数或类似操作,它不会在创建副本时使多个指针指向同一对象。事实上,这是非常不同的。 自动PTR 是赋值运算符修改 来源 对象。想想这个无耻的插头 auto_ptr wikipedia page :

    int *i = new int;
    auto_ptr<int> x(i);
    auto_ptr<int> y;
    
    y = x;
    
    cout << x.get() << endl; // Print NULL
    cout << y.get() << endl; // Print non-NULL address i
    

    注意如何执行

    y = x;
    

    不仅修改Y,还修改X。

    这个 boost::shared_ptr 模板使处理指向同一对象的多个指针变得容易,并且只有在对该对象的最后一个引用超出范围后,才会删除该对象。此功能在您的场景中不有用,该场景(尝试)实现 Singleton . 在您的场景中,总是有0对1的引用引用指向类的唯一对象(如果有的话)。

    本质上, 自动PTR 对象和 SelddPPTR 对象具有完全不同的语义(这就是为什么您不能在容器中使用前者,但对后者这样做是很好的),我当然希望您有良好的测试来捕获在移植代码时引入的任何回归。:-}

        2
  •  14
  •   Josh Kelley    15 年前

    其他人已经回答了为什么此代码使用 auto_ptr 而不是 shared_ptr . 要解决其他问题:

    什么/如何替换此实现?

    要么使用 boost::scoped_ptr unique_ptr (在Boost和新C++标准中都可用)。两个 scoped_ptr 尤尼奎 提供严格的所有权(并且没有引用计数开销),避免对 自动PTR .

    此外,您是否有其他理由考虑使用 自动PTR 而不是 SelddPPTR ?你看到有什么问题转移到 SelddPPTR 未来?

    就个人而言,我不会使用 自动PTR . 复制时删除太不直观了。 Herb Sutter seems to agree . 切换到 范围范围 , 尤尼奎 SelddPPTR 应该没有问题。明确地, SelddPPTR 如果您不关心引用计数开销,则应该是一个替换项。 范围范围 如果您不使用 自动PTR 的所有权转移能力。如果您使用所有权转让,那么 尤尼奎 几乎是替换的一部分,只不过需要显式调用 move 转让所有权。见 here 举个例子。

        3
  •  1
  •   anon    15 年前

    自动指针是我唯一使用的智能指针。我之所以使用它是因为我不使用Boost,而且通常我更喜欢使用面向业务/应用程序的类来显式地 定义删除语义和顺序,而不是依赖于 智能指针的集合或单个智能指针的集合。