Android本机强指针vs std::shared\u ptr

Android本机强指针vs std::shared\u ptr,android,c++,c++11,std,native,Android,C++,C++11,Std,Native,我指的是,而且 在强指针的Android实现中,任何基于强指针的对象都必须继承refbase,即 sp<TheClass> theObj // TheClass must inherit from class RefBase 为了使调用incStrong或decStrong不会失败other和mPtr必须继承RefBase 问题 为什么sp的实现要求其管理的obj必须是RefBase的子对象?甚至没有办法在编译时甚至运行时强制执行此要求。(如果(type()…),那么可能是) …

我指的是,而且

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

sp<TheClass> theObj // TheClass must inherit from class RefBase
为了使调用
incStrong
decStrong
不会失败
other
mPtr
必须继承
RefBase

问题

为什么
sp
的实现要求其管理的obj必须是
RefBase
的子对象?甚至没有办法在编译时甚至运行时强制执行此要求。(如果(type()…),那么可能是


进一步思考后,答案是这提供了灵活性吗?

如果是,这是如何提供灵活性的?

它可以节省内存分配。当您写入时:

std::shared_ptr<Foo> pFoo{new Foo(bar)};
std::shared_ptr pFoo{new Foo(bar)};
pFoo
实际上有一个指向共享数据结构(在堆上分配)的指针,该结构有引用计数器和指向实际Foo对象的指针。通过使对象从
RefBase
派生,可以将引用计数嵌入对象本身(节省额外的内存分配)

有趣的是,对于C++11以后的版本,您可以通过使用
std::make_shared
来避免额外的内存分配,它将执行单个内存分配,并在其中构造共享数据结构和Foo对象

没有对来自
RefBase
的派生进行编译时检查的事实是粗心大意。
m_ptr
应该声明为
RefBase*m_ptr
,然后声明为
操作符*
(etc)应该对
T*
进行静态转换。事实上,我可能会使
sp
sp\u base
继承,后者将比较运算符作为公共,其他函数作为受保护

编辑


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

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

因此,对于共享ptr,您可能需要:


对于sp,您几乎可以安全地将原始指针传递给sp构造函数。

您确定您的示例对于
shared\u ptr
合法吗?对于类
sp
,该赋值是合法的。我没有显示赋值运算符,而是显示了初始化。如果您想使用shared\u ptr执行赋值,则必须是:
pFoo=shared\u ptr(new Foo(bar));
…这是侵入式指针的另一个优点。(而且你不必玩这个
shared_的愚蠢游戏)。这不是赋值运算符的用法,但这并不意味着它是有效的(事实并非如此)。
std::shared_ptr<Foo> pFoo{new Foo(bar)};