基 class 中 boost::shared_ptr 指向的对象永远不会被销毁
Object pointed by boost::shared_ptr in base class is never destroyed
我对 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
构建的 arm64 boost 1_57
有什么想法吗?
以下代码说明了一个工作示例。它使用从 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();
}
显而易见的答案是您有多个 shared_ptr
引用一个对象,因此重置一个会减少引用计数但不会删除该对象。
即使未在 A
和 B
之外引用 shared_ptr
,也会发生这种情况。如果您分配 A
或 B
而不重载 operator=
或复制 A
或 B
(例如,按值传递,return 按值传递)而没有重载复制构造函数,那么就会产生这样的结果。
您可以通过多种方式进行调查。
- 您可以检查
CleanMyObject
中的 boost::shared_ptr::use_count()
是否大于 1。
- 如果您不想共享和引用计数,您可以将
boost::shared_ptr
替换为 std::unique_ptr
或 boost::scoped_ptr
。
- 如果您想确保没有意外复制或分配
A
或 B
,您可以从 boost::noncopyable
.[=40= 派生 A
]
按照@Josh Kelley 的建议,使用 unique_ptr 解决了我的问题。
所以我把注意力转移到boost::shared_ptr上来了解问题出在哪里。事实证明,使用标志 BOOST_AC_USE_PTHREADS 和 BOOST_SP_USE_PTHREADS 为 iOS 构建提升是奇怪的最初原因。基于:
1) 安迪温斯坦的回答: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/)
很明显我应该使用自旋锁,即 BOOST_SP_USE_SPINLOCK 用于构建提升的标志。
在我使用 BOOST_SP_USE_SPINLOCK 标志重建 boost 后,问题似乎得到了解决。
我对 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
构建的 arm64 boost 1_57有什么想法吗?
以下代码说明了一个工作示例。它使用从 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();
}
显而易见的答案是您有多个 shared_ptr
引用一个对象,因此重置一个会减少引用计数但不会删除该对象。
即使未在 A
和 B
之外引用 shared_ptr
,也会发生这种情况。如果您分配 A
或 B
而不重载 operator=
或复制 A
或 B
(例如,按值传递,return 按值传递)而没有重载复制构造函数,那么就会产生这样的结果。
您可以通过多种方式进行调查。
- 您可以检查
CleanMyObject
中的boost::shared_ptr::use_count()
是否大于 1。 - 如果您不想共享和引用计数,您可以将
boost::shared_ptr
替换为std::unique_ptr
或boost::scoped_ptr
。 - 如果您想确保没有意外复制或分配
A
或B
,您可以从boost::noncopyable
.[=40= 派生A
]
按照@Josh Kelley 的建议,使用 unique_ptr 解决了我的问题。
所以我把注意力转移到boost::shared_ptr上来了解问题出在哪里。事实证明,使用标志 BOOST_AC_USE_PTHREADS 和 BOOST_SP_USE_PTHREADS 为 iOS 构建提升是奇怪的最初原因。基于:
1) 安迪温斯坦的回答: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/)
很明显我应该使用自旋锁,即 BOOST_SP_USE_SPINLOCK 用于构建提升的标志。
在我使用 BOOST_SP_USE_SPINLOCK 标志重建 boost 后,问题似乎得到了解决。