但这就是我想要实现的目标吗?
关键是如果没有更清晰的描述,我们就无法判断。这听起来很简单:信号专门用于解耦调用者和被调用者。
所以让我为你编造你的“虚拟代码”。我将回避您在该行中显示的巨大的类型过度复杂性:
boost::signals2::connection tria_signal =
/*...*/.connect(boost::signals2::signal<void()>::slot_type(
&Solid::call_this_function, pointer_M.get())
.track(pointer_M));
插槽的整个想法是它们使用类型擦除来概括可调用对象。只需以任何兼容的形式提供您的可调用对象,然后让库推断出神秘的实现类型。
住在科利鲁
#include <boost/signals2.hpp>
#include <boost/make_shared.hpp>
#include <iostream>
struct OtherClass {
OtherClass(...) {}
boost::signals2::signal<void()> tria;
void test() {
if (!tria.empty())
tria();
}
};
struct Solid {
boost::shared_ptr<OtherClass> pointer_M;
Solid() {
pointer_M = boost::make_shared<OtherClass>(1,2,3);
auto tria_signal = pointer_M->tria.connect(
boost::bind(&Solid::call_this_function, this));
}
private:
void call_this_function() {
std::cout << "Solid was here" << std::endl;
};
};
int main() {
Solid s;
s.pointer_M->test();
}
印刷
Solid was here
水晶球:我们能猜出问题吗?
也许我们可以猜到问题所在:看起来您正在努力跟踪 所指向的对象的生命周期pointer_M
。这没有用,因为它OtherClass
首先拥有信号,这意味着当信号OtherClass
消失时所有连接都会断开。
正确的终身管理
您可能想要的是在Solid
对象的生命周期结束时断开连接,而不是OtherClass
. 一般来说,我建议scoped_connection
在这里使用:
住在科利鲁
#include <boost/signals2.hpp>
#include <boost/make_shared.hpp>
#include <iostream>
struct OtherClass {
OtherClass(...) {}
boost::signals2::signal<void()> tria;
void test() {
if (!tria.empty())
tria();
}
};
struct Solid {
boost::shared_ptr<OtherClass> pointer_M;
Solid() {
pointer_M = boost::make_shared<OtherClass>(1,2,3);
tria_signal = pointer_M->tria.connect(
boost::bind(&Solid::call_this_function, this));
}
private:
boost::signals2::scoped_connection tria_signal;
void call_this_function() {
std::cout << "Solid was here" << std::endl;
};
};
int main() {
boost::shared_ptr<OtherClass> keep;
{
Solid s;
std::cout << "Testing once:" << std::endl;
s.pointer_M->test();
keep = s.pointer_M; // keep the OtherClass alive
} // destructs Solid s
std::cout << "Testing again:" << std::endl;
keep->test(); // no longer connected, due to scoped_connection
}
印刷
Testing once:
Solid was here
Testing again:
简化
在您的情况下, theOtherClass
已经由 the 拥有Solid
(至少它是创建的)。似乎根本不需要共享指针:
住在科利鲁
#include <boost/signals2.hpp>
#include <boost/make_shared.hpp>
#include <iostream>
struct OtherClass {
OtherClass(...) {}
boost::signals2::signal<void()> tria;
void test() {
if (!tria.empty())
tria();
}
};
struct Solid {
Solid() : oc_M(1,2,3) {
tria_signal = oc_M.tria.connect(
boost::bind(&Solid::call_this_function, this));
}
void test() { oc_M.test(); }
private:
OtherClass oc_M;
boost::signals2::scoped_connection tria_signal;
void call_this_function() {
std::cout << "Solid was here" << std::endl;
};
};
int main() {
Solid s;
s.test();
}
因为成员以相反的声明顺序被破坏,所以这是完全安全的。
建筑 航天
如果您知道自己在做什么,并且pointer_M
实际上需要共享,那么您可能想要跟踪该指针。Solid
您可能也应该考虑制作enable_shared_from_this
. 如果您想成为真正的“企业级工程师™”,您也许可以对别名构造函数做一些花哨的事情:shared_ptr 的别名构造函数是干什么用的?