在基类中由boost :: shared_ptr指向的对象永远不会被销毁

时间:2015-02-27 20:08:13

标签: c++ ios boost shared-ptr arm64

我对boost shared_ptr有一个奇怪的问题:

class A
{

    A( )
    : m_myObjectPtr( new MyObject( ) )
    {

    }

    protected:

    boost::shared_ptr<MyObject> m_myObjectPtr; // MyObject class is a simple class with a constructor and destructor
};

class B : A
{
    B( )
    {

    }

    void CleanMyObject( )
    {
        m_myObjectPtr.reset( );
    }
};

class MyObject
{
    MyObject( )
    {
        cout << "Constructed MyObject" << endl;
    }

    ~MyObject( )
    {
        cout << "Destroyed MyObject" << endl;
    }
};

我的问题是,当我调用B :: CleanMyObject()时,永远不会调用MyObject的析构函数。永远不会打印“Destroyed MyObject”。

我在iOS上看到这个,使用https://github.com/danoli3/ofxiOSBoost/blob/master/scripts/build-libc%2B%2B.sh

构建了boost64构建的boost 1_57

有什么想法吗?

3 个答案:

答案 0 :(得分:3)

显而易见的答案是,您有多个shared_ptr引用单个对象,因此重置一个会减少引用计数,但不会删除该对象。

即使shared_ptr未在AB之外引用,也会发生这种情况。如果您指定AB而不重载operator=或复制AB(例如,按值传递,按值返回),而不会重载复制构造函数,这将导致结果。

您可以通过多种方式进行调查。

  • 您可以在CleanMyObject中查看boost::shared_ptr::use_count(),看看它是否大于1。
  • 如果您不想要分享和引用计数,则可以将boost::shared_ptr替换为std::unique_ptrboost::scoped_ptr
  • 如果您想确保不会意外复制或分配AB,则可以从boost::noncopyable派生A

答案 1 :(得分:2)

以下代码说明了一个工作示例。它使用从C ++ 11开始的std命名空间中的shared_ptr<T>,但您可以替换boost::shared_ptr<T>

正如您尝试的那样,在MyObject::~MyObject的调用中调用

B::CleanMyObject

#include <memory>
#include <iostream>
using namespace std;

class MyObject
{
public:
    MyObject()
    {
        cout << "Constructed MyObject" << endl;
    }

    ~MyObject()
    {
        cout << "Destroyed MyObject" << endl;
    }
};

class A
{
protected:
    A()
    : m_myObjectPtr(new MyObject())
    {

    }

    std::shared_ptr<MyObject> m_myObjectPtr; // MyObject class is a simple class with a constructor and destructor
};

class B : A
{
public:
    B()
    {

    }
    void CleanMyObject()
    {
        m_myObjectPtr.reset();
    }
};

int main() {
    B b;
    b.CleanMyObject();
}

答案 2 :(得分:2)

按照@Josh Kelley的建议,使用unique_ptr解决了我的问题。

所以我将注意力转移到boost :: shared_ptr以了解问题所在。事实证明,使用标志BOOST_AC_USE_PTHREADS和BOOST_SP_USE_PTHREADS构建iOS的提升是奇怪的原因。基于:

1)Andy Weinstein回答:Boost threads: in IOS, thread_info object is being destructed before the thread finishes executing

2)弱的CPU教程(http://preshing.com/20121019/this-is-why-they-call-it-a-weakly-ordered-cpu/

很明显,我应该使用Spin Lock,即BOOST_SP_USE_SPINLOCK标志来构建提升。

使用BOOST_SP_USE_SPINLOCK标志重建boost后,问题似乎得到解决。