我在具有GCC version 2.95
的嵌入式Linux环境中使用C ++。
我无法用bcp提取boost::shared_ptr
个文件,它太重了。
我想要的是boost::shared_ptr
的简单智能指针实现,但没有所有boost
开销(如果可能的话......)。
我可以提出我自己的版本阅读提升源但我担心错过一个或多个点,似乎很容易制作一个错误的智能指针,我不能承担错误的实施。
那么,boost::shared_ptr
(或任何引用计数等效智能指针)的“简单”实现或实现示例是否存在,我可以使用或者我可以作为灵感?
答案 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
的唯一开销是:
BOOST_DISABLE_THREADS
来禁用它。make_shared()
或allocate_shared()
创建对象来消除额外分配。在许多情况下,您可以通过不创建对象或复制共享指针来消除速度关键代码的开销 - 通过引用传递指针并仅在实际需要时复制它们。
如果你需要某些指针的线程安全,而不是其他指针,并且(在分析之后,删除所有不必要的分配和指针复制),你发现使用共享指针仍然会导致很大的开销,那么你可以考虑使用{ {1}},并在对象内管理您自己的引用计数。
如果可行的话,更新到现代GNU / Linux版本可能也有好处。自Linux 2.6中引入futex以来,线程同步效率更高。你也可以在其他方面找到这个帮助;过去十年中有很多改进。更现代的编译器也会提供标准(TR1或C ++ 11)共享指针,因此您不需要Boost。
答案 3 :(得分:3)
我建议您可以单独使用shared_ptr。但是,如果您正在寻找简单的实现
答案 4 :(得分:1)
您可以在没有所有Boost开销的情况下使用shared_ptr
:它是一个仅限标头的实现。如果您不使用任何其他类,则只编译shared_ptr
。
shared_ptr
的实现已经非常精简了,但是如果你想避免中间引用计数块和对删除函数的(潜在)虚拟调用,你可以改用boost::intrusive_ptr
,这是更适合嵌入式环境:它在嵌入在对象本身的引用计数器上运行,您只需提供几个函数来递增/递减它。缺点是您将无法使用weak_ptr
。
我无法评论gcc 2.95如何内联/折叠模板实例化(它是一个非常旧的编译器),更新版本的gcc处理得相当好,所以你在这里独自一人