【问题标题】:Android native strong pointer vs std::shared_ptrAndroid 原生强指针 vs std::shared_ptr
【发布时间】:2017-02-09 16:49:18
【问题描述】:

我指的是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

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

【问题讨论】:

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


    【解决方案1】:

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

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

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

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

    没有对RefBase 的派生进行编译时检查的事实是粗心。 m_ptr 应该被声明为RefBase *m_ptr,然后operator * (etc) 应该对T* 进行静态转换。事实上,我可能会让sp&lt;T&gt; 继承自sp_base,后者将比较运算符设为public,而将其他函数设为protected。

    编辑

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

    【讨论】:

    【解决方案2】:

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

    所以对于 shared_ptr 你可能需要这个: http://en.cppreference.com/w/cpp/memory/enable_shared_from_this

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

    【讨论】:

      猜你喜欢
      • 2013-08-18
      • 2012-09-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-11-15
      • 1970-01-01
      • 2016-04-14
      相关资源
      最近更新 更多