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

Alternative to boost::shared_ptr in an embedded environment

本文关键字:方案 ptr shared 环境 boost 嵌入式      更新时间:2023-10-16

我在嵌入式linux环境中使用c++,该环境有GCC version 2.95 .

我不能用bcp提取boost::shared_ptr文件,它太重了。

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

我可以提出我自己的版本读取boost源,但我担心错过一个或多个点,似乎很容易使一个错误的智能指针,我不能有一个错误的实现。

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

如果您不需要混合共享 ptr,并且不需要自定义删除器,您可以使用快速而肮脏的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>( ... );

还有std::tr1::shared_ptr,这只是c++ 11标准对boost的提升。如果允许的话,您可以选择它,或者使用引用计数自己编写。

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

  • 和一些单元测试
  • 不是线程安全的
  • 对多态赋值的基本支持 <—如果您感兴趣,请告诉我
  • 自定义删除器(即数组删除器,或特殊资源的自定义函数)
创建一个非线程安全的shared_ptr

您关心的是哪些"boost开销",以及在哪些方面shared_ptr对您的应用程序来说"太重"?使用Boost不会带来任何开销(至少如果你只使用头文件库,比如智能指针库);我能想到的关于shared_ptr的唯一开销是:

    线程安全引用计数;由于您使用的是古老的编译器,我假定您也有古老的运行时库和内核,因此这可能非常低效。如果你的应用程序是单线程的,那么你可以通过# define BOOST_DISABLE_THREADS来禁用它。
  • 与托管对象一起分配引用计数结构。您可以通过使用make_shared()allocate_shared()创建对象来消除额外的分配。

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

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

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

您可以使用shared_ptr而不需要所有Boost开销:它是一个仅标头的实现。如果您不使用任何其他类,只有shared_ptr将在。

中编译。

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

我不能评论gcc 2.95如何内联/折叠模板实例化(它是一个非常旧的编译器),最近版本的gcc处理得相当好,所以你自己看。