嵌入式环境中boost :: shared_ptr的替代方案

时间:2011-10-17 09:48:24

标签: c++ boost embedded smart-pointers

我在具有GCC version 2.95的嵌入式Linux环境中使用C ++。

我无法用bcp提取boost::shared_ptr个文件,它太重了。

我想要的是boost::shared_ptr的简单智能指针实现,但没有所有boost开销(如果可能的话......)。

我可以提出我自己的版本阅读提升源但我担心错过一个或多个点,似乎很容易制作一个错误的智能指针,我不能承担错误的实施。

那么,boost::shared_ptr(或任何引用计数等效智能指针)的“简单”实现或实现示例是否存在,我可以使用或者我可以作为灵感?

5 个答案:

答案 0 :(得分:10)

如果您不需要混合共享 ptr,并且不需要 coustom deletors ,您可以快速使用和脏my_shared_ptr:

template<class T>
class my_shared_ptr
{
    template<class U>
    friend class my_shared_ptr;
public:
    my_shared_ptr() :p(), c() {}
    explicit my_shared_ptr(T* s) :p(s), c(new unsigned(1)) {}

    my_shared_ptr(const my_shared_ptr& s) :p(s.p), c(s.c) { if(c) ++*c; }

    my_shared_ptr& operator=(const my_shared_ptr& s) 
    { if(this!=&s) { clear(); p=s.p; c=s.c; if(c) ++*c; } return *this; }

    template<class U>
    my_shared_ptr(const my_shared_ptr<U>& s) :p(s.p), c(s.c) { if(c) ++*c; }

    ~my_shared_ptr() { clear(); }

    void clear() 
    { 
        if(c)
        {
            if(*c==1) delete p; 
            if(!--*c) delete c; 
        } 
        c=0; p=0; 
    }

    T* get() const { return (c)? p: 0; }
    T* operator->() const { return get(); }
    T& operator*() const { return *get(); }

private:
    T* p;
    unsigned* c;
}

对于对make_my_shared<X>感兴趣的任何人,可以将其简单地实现为

template<class T, class... U>
auto make_my_shared(U&&... u)
{ 
    return my_shared_ptr<T>(new T{std::forward<U>(u)...});
}

被称为

auto pt = make_my_shared<T>( ... );

答案 1 :(得分:4)

还有std :: tr1 :: shared_ptr,它只是C ++ 11标准从boost中解除的。如果允许,你可以选择它,或者用引用计数编写你自己的。

答案 2 :(得分:3)

你担心哪些“提升开销”,以及shared_ptr“对你的应用程序来说”太重了“?使用Boost没有任何开销(至少如果你只使用只有头的库,比如智能指针库);我能想到的关于shared_ptr的唯一开销是:

  • 线程安全引用计数;既然你使用的是古老的编译器,我假设你还有一个古老的运行时库和内核,所以这可能是非常低效的。如果您的应用程序是单线程的,那么您可以通过#defining BOOST_DISABLE_THREADS来禁用它。
  • 在托管对象旁边分配引用计数结构。您可以使用make_shared()allocate_shared()创建对象来消除额外分配。

在许多情况下,您可以通过不创建对象或复制共享指针来消除速度关键代码的开销 - 通过引用传递指针并仅在实际需要时复制它们。

如果你需要某些指针的线程安全,而不是其他指针,并且(在分析之后,删除所有不必要的分配和指针复制),你发现使用共享指针仍然会导致很大的开销,那么你可以考虑使用{ {1}},并在对象内管理您自己的引用计数。

如果可行的话,更新到现代GNU / Linux版本可能也有好处。自Linux 2.6中引入futex以来,线程同步效率更高。你也可以在其他方面找到这个帮助;过去十年中有很多改进。更现代的编译器也会提供标准(TR1或C ++ 11)共享指针,因此您不需要Boost。

答案 3 :(得分:3)

我建议您可以单独使用shared_ptr。但是,如果您正在寻找简单的实现

  • 进行一些单元测试
  • 非线程安全
  • 对多态分配的基本支持&lt; - 让我知道你是否感兴趣
  • 自定义deletors(即数组deletors,或特殊资源的自定义functor)

请点击此处: Creating a non-thread safe shared_ptr

答案 4 :(得分:1)

您可以在没有所有Boost开销的情况下使用shared_ptr:它是一个仅限标头的实现。如果您不使用任何其他类,则只编译shared_ptr

shared_ptr的实现已经非常精简了,但是如果你想避免中间引用计数块和对删除函数的(潜在)虚拟调用,你可以改用boost::intrusive_ptr,这是更适合嵌入式环境:它在嵌入在对象本身的引用计数器上运行,您只需提供几个函数来递增/递减它。缺点是您将无法使用weak_ptr

我无法评论gcc 2.95如何内联/折叠模板实例化(它是一个非常旧的编译器),更新版本的gcc处理得相当好,所以你在这里独自一人