关于boost::shared_ptr
的问题:
我有3个课程。
A
是某种Main类,负责管理所有内容。
B
是一个只具有完成某些工作的功能的类。
Dispatcher
只是一个包含一个单独线程的类,它从这个线程中的B
的Instaces获得工作。
所以它的工作方式如下:A
的实例为Dispatcher
。现在,A
生成B
的实例并将其传递给调度员。
重要的是,B
需要在A::callback()
完成后调用B
。这就是class A : public boost::enable_shared_from_this<A>
{
public:
A();
void sendB();
void callback();
private:
Dispatcher m_Dispatcher;
};
在其构造函数中获取对A的引用的原因(参见下面的代码)
A.hpp
class B
{
public:
B(boost::shared_ptr<A> ptr);
boost::shared_ptr<A> m_PointerToA;
/* Some other functions */
};
B.hpp
class Dispatcher
{
public:
void run();
void dispatch(boost::shared_ptr<B> b);
private:
void doWork();
boost::thread m_Thread;
};
Dispatcher.hpp
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);
}
A.cpp
B::B(boost::shared_ptr<A> ptr) :
: m_PointerToA(ptr)
{
}
B.cpp
int main()
{
A instanceA;
while(true)
{
instanceA.sendB();
/* Do some other stuff */
}
return 0;
}
main_example.cpp
shared_ptr
所以我的问题是:
为此目的使用boost :: shared_ptr是否合理?
我不确定B
是否适合去这里。我的问题是,当我从this
调用构造函数并将shared_ptr
指针传递给它时,我不知道究竟发生了什么。现在根据m_PointerToA
我会假设A
取得Dispatcher
的所有权。但这意味着当B
中的工作完成并且我的m_PointerToA
实例被删除时,它也会删除对A
的引用,这实际上意味着它会杀死对象本身尽管事实上,主循环中存在{{1}}的实际实例。
更新
添加了一些代码和更新的问题本身,以使其更加清晰。
答案 0 :(得分:4)
这种设计没有什么特别的错误。不过我更愿意使用boost::function<>
&amp; boost::bind
。它为回调提供了更好的灵活性,并且不会将B紧密地绑定到A.当然,您仍然需要改变常见的线程警告。
答案 1 :(得分:1)
是的,只需复制/分配shared_ptr
即可,只会增加引用次数。
在您的示例中,shared_from_this()
将从shared_ptr
{引用weak_ptr
(引用计数1)创建一个(此处:临时)this
,所以当您assign / copy-construct m_PointerToA
,引用计数将在ctor返回之前暂时增加到2,临时对象将被销毁,再次将引用计数减少到1(shared_ptr是&#34;意识到&#34;您B
对象中的一个实例。
所以,是的,如果B被删除,它将在这种情况下破坏A(因为引用计数降为0)。
您的关注
这意味着如果我的B实例被删除,它也会删除m_PointerToA,这也会杀死我的A实例。当然,
A
的原始实例存在于其他地方。
仅显示如果您计划/需要/打算保留指向A
实例的指针以供进一步使用,您应该使用shared_ptr
而不是原始指针。如果您可以控制A
的界面,最简单的方法是named constructor,如下所示:
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() );
}
然后,即使您的B
实例被删除,A
的实例仍然存在,因为shared_ptr
的引用计数仍然(至少)为1。