[英]Appropriate use for boost::shared_ptr?
A question about boost::shared_ptr
here: 关于boost::shared_ptr
问题:
I have 3 Classes. 我有3个课程。
A
is some kind of Main class which is responsible to manage everything. A
是某种Main类,负责管理一切。
B
is a class which just has functions to do some work. B
是一个只具有完成某些工作的功能的类。
Dispatcher
is just a class which wraps around a seperate thread, which gets the work from Instaces of B
done in this thread. Dispatcher
只是一个包装单独线程的类,它从这个线程中的B
Instaces获得工作。
So it is kinda working like this: A
has an instance of Dispatcher
. 所以它有点像这样工作: A
有一个Dispatcher
实例。 Now on occassion A
generates an instance of B
and passes it to the dispatcher. 现在,在场合A
生成B
的实例并将其传递给调度员。
The important part is, that B
needs to call A::callback()
when it's done. 重要的是, B
需要调用A::callback()
。 This is why B
gets a reference to A in it's constructor ( see code below ) 这就是B
在它的构造函数中获取对A的引用的原因(参见下面的代码)
A.hpp A.hpp
class A : public boost::enable_shared_from_this<A>
{
public:
A();
void sendB();
void callback();
private:
Dispatcher m_Dispatcher;
};
B.hpp B.hpp
class B
{
public:
B(boost::shared_ptr<A> ptr);
boost::shared_ptr<A> m_PointerToA;
/* Some other functions */
};
Dispatcher.hpp Dispatcher.hpp
class Dispatcher
{
public:
void run();
void dispatch(boost::shared_ptr<B> b);
private:
void doWork();
boost::thread m_Thread;
};
A.cpp A.cpp
A::A()
{
m_Dispatcher.run();
}
void A::sendB()
{
boost::shared_ptr ptr_B;
ptr_B.reset(new B(this->shared_from_this);
m_Dispatcher.dispatch(ptr_B);
}
B.cpp B.cpp
B::B(boost::shared_ptr<A> ptr) :
: m_PointerToA(ptr)
{
}
main_example.cpp main_example.cpp
int main()
{
A instanceA;
while(true)
{
instanceA.sendB();
/* Do some other stuff */
}
return 0;
}
So my question is: 所以我的问题是:
Is it reasonable to use boost::shared_ptr for this purpose? 为此目的使用boost :: shared_ptr是否合理?
I am not sure if the shared_ptr
is the right thing to go here. 我不确定shared_ptr
是否适合去这里。 My problem is, that I don't know what happens exactly when I call the constructor from B
and pass it the this
pointer. 我的问题是,当我从B
调用构造函数并将其传递给this
指针时,我不知道究竟发生了什么。 Now according to shared_ptr
I would assume that m_PointerToA
takes ownership of A
. 现在根据shared_ptr
我会假设m_PointerToA
取得A
所有权。 But this would mean that when the work in the Dispatcher
is done and my instance of B
gets deleted it would also delete the reference to m_PointerToA
which would actually mean it kills the object itself despite the fact there is an actual instance of A
in the main loop. 但这意味着当Dispatcher
中的工作完成并且我的B
实例被删除时,它也会删除对m_PointerToA
的引用,这实际上意味着它会杀死对象本身,尽管事实上主要有A
实例环。
Update: 更新:
Added some code and updated question itself to make it more clear. 添加了一些代码和更新的问题本身,以使其更清晰。
There's nothing particular wrong with this design. 这种设计没有什么特别的错误。 However I would prefer to instead use boost::function<>
& boost::bind
. 但是我宁愿使用boost::function<>
和boost::bind
。 It gives you way better flexibility for the callback and doesn't tie B as tightly to A. Of course you still have to be vary of the usual threading caveats. 它为回调提供了更好的灵活性,并且不会将B紧密地绑定到A.当然,您仍然需要改变通常的线程警告。
Yes, it is okay to just copy/assign a shared_ptr
, it will only increase the reference count. 是的,可以只复制/分配shared_ptr
,它只会增加引用计数。
In your example, shared_from_this()
will create a (here: temporary) shared_ptr
from the weak_ptr
that is hold by this
(ref count 1), so when you assign/copy-construct m_PointerToA
, the reference count will increase temporarily to 2 before the ctor returns and the temporary object will be destroyed, decreasing the reference count to 1 again (the shared_ptr is "aware" of the one instance in your B
object). 在你的榜样, shared_from_this()
将创建一个:(这里暂时) shared_ptr
从weak_ptr
是通过持有this
(引用计数1),所以当你分配/拷贝构造m_PointerToA
,引用计数会前临时增加至2 ctor返回并且临时对象将被销毁,再次将引用计数减少到1(shared_ptr“知道” B
对象中的一个实例)。
So, yes, if B is deleted, it will destroy A in this case (as the reference count drops to 0). 所以,是的,如果B被删除,它将在这种情况下销毁A(因为引用计数降为0)。
Your concern 你所关心的
This would mean if my Instance of B is deleted, it would also delete m_PointerToA which would also kill my instance of A . 这意味着如果我的B实例被删除,它也会删除m_PointerToA,这也会杀死我的A实例。 Of course my original instance of
A
is held elsewhere. 当然,我原来的A
实例是在其他地方举行的。
only shows that if you plan/need/intend to keep a pointer to the instance of A
for further usage, you should do so with a shared_ptr
as well instead of a raw pointer. 只显示如果您计划/需要/打算保留指向A
实例的指针以供进一步使用,您应该使用shared_ptr
而不是原始指针。 If you have control of A
's interface, the easiest way would be a named constructor like this: 如果您可以控制A
的接口,最简单的方法就是命名构造函数,如下所示:
class A : public boost::enable_shared_from_this<A> {
public:
static boost::shared_ptr<A> create();
void initClassB();
// ....
private:
A();
A( const A & other );
A& operator=( const A & rhs );
};
boost::shared_ptr<A> A::create() {
return boost::shared_ptr<A>( new A() );
}
Then, even if your instance of B
is deleted, the instance of A
will still survive because the reference count of the shared_ptr
is still (at least) 1. 然后,即使您的B
实例被删除, A
的实例仍然存在,因为shared_ptr
的引用计数仍然(至少)为1。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.