Android 原生强指针 vs std::shared_ptr.

Android native strong pointer vs std::shared_ptr

本文关键字:shared ptr std vs 原生 指针 Android      更新时间:2023-10-16

我指的是 Refbase.h、Refbase.cpp 和 StrongPointer.h

在强指针的 Android 实现中,任何基于强指针的对象都必须继承 refbase,即

sp<TheClass> theObj // TheClass must inherit from class RefBase

这个要求可以在sp方法之一的代码中看到:

template<typename T> sp<T>& sp<T>::operator =(T* other) {
if (other != NULL) {
other->incStrong(this);
}
if (mPtr != NULL) {
mPtr->decStrong(this);
}
mPtr = other;
return *this; 
}

为了让呼叫incStrongdecStrong不失败......othermPtr必须继承RefBase

问题

为什么sp实现时,它所管理的对象必须是RefBase的子级?甚至没有办法在编译时甚至运行时强制实施此要求。(好吧,也许if(type()...)

标准库没有这样的要求


经过进一步思考,答案是否提供了灵活性?
如果是,这如何提供灵活性?

它节省了内存分配。当你写:

std::shared_ptr<Foo> pFoo{new Foo(bar)};

pFoo实际上有一个指向共享数据结构(在堆上分配)的指针,该结构具有引用计数器和指向实际 Foo 对象的指针。 通过使对象派生自RefBase,可以将引用计数嵌入到对象本身中(节省额外的内存分配)。

有趣的是,从 C++11 开始,您可以通过使用std::make_shared<Foo>来避免额外的内存分配,这将执行单个内存分配并构造共享数据结构和其中的 Foo 对象。

事实上,没有对RefBase派生进行编译时检查是粗心大意的。m_ptr应该被声明为RefBase *m_ptr,然后operator *(等)应该对T*进行static_cast。 事实上,我可能会sp<T>继承比较运算符为公共,其他函数为受保护sp_base

编辑

再三考虑,有相当多的编译时检查。 如果T没有incStrong成员,编译将失败,除非它派生自RefBase,否则几乎可以肯定不会。 我仍然认为将T*转换为RefBase*会是一个更好的检查,但那里的那个可能已经足够好了。

它自动允许您从实现 RefBase 的任何对象创建 sp,而对于共享指针,您可以在尝试将原始指针包装到共享指针时射击自己的脚。

因此,对于shared_ptr您可能需要: http://en.cppreference.com/w/cpp/memory/enable_shared_from_this

对于 SP,您几乎可以安全地将原始指针传递给 SP Contructor。