Android原生强指针vs std :: shared_ptr

时间:2017-02-09 16:49:18

标签: android c++ c++11 std native

我指的是Refbase.hRefbase.cppStrongPointer.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已实施,以便其管理的obj 必需成为RefBase的孩子?甚至没有办法在编译时甚至运行时强制执行此要求。 (好吧if(type()...

Std library doesn't have such a requirement

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

2 个答案:

答案 0 :(得分:0)

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

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

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

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

没有编译时间检查m_ptr的派生是粗心的事实。 RefBase *m_ptr应该已声明为operator *,然后T*(等)应该对sp<T>执行static_cast。实际上,我可能会将sp_base继承自T,其中比较运算符为public,其他函数为protected。

修改

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

答案 1 :(得分:0)

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

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

对于sp,

几乎可以安全地将原始指针传递给sp contructor。