我对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有什么想法吗?
答案 0 :(得分:3)
显而易见的答案是,您有多个shared_ptr
引用单个对象,因此重置一个会减少引用计数,但不会删除该对象。
即使shared_ptr
未在A
和B
之外引用,也会发生这种情况。如果您指定A
或B
而不重载operator=
或复制A
或B
(例如,按值传递,按值返回),而不会重载复制构造函数,这将导致结果。
您可以通过多种方式进行调查。
CleanMyObject
中查看boost::shared_ptr::use_count()
,看看它是否大于1。boost::shared_ptr
替换为std::unique_ptr
或boost::scoped_ptr
。A
或B
,则可以从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后,问题似乎得到解决。