假设单击“按钮”,将触发btn_Click
事件处理程序。
我有sender
,该参数包含对引发事件的控件/对象的引用。发送者部分将是对单击的按钮的引用。如果控件将事件引发给自己,请中止该过程(只需调用return即可)。
struct EventArgs { /* The arguments of the event */ };
struct A { int x; virtual ~A() = default; };
struct B { int y; virtual ~B() = default; };
struct C : public virtual A, public virtual B {
void btn_Click(void* sender, EventArgs* e) {
if (sender == static_cast<void*>(this)) return;
else { /* Handle the event */ }
}
};
int main() {
A* a = new C();
dynamic_cast<C*>(a)->btn_Click(a, nullptr);
}
假设发件人为a
,则上面的代码sender == this
的计算结果为false。
我该怎么做才能使它返回true?我认为我需要创建一个包含所有this
指针的数组,然后将sender
与所有指针进行比较。
答案 0 :(得分:2)
我认为您确实需要与所有子对象进行比较,但是写一个函数比使用数组要好:
struct C: A, B
{
bool is(void* that) const
{
return this == that
|| static_cast<const A*>(this) == that
|| static_cast<const B*>(this) == that;
}
void btn_Click(void* sender, EventArgs* e) {
if (this->is(sender)) return;
// ...
}
}
请注意,强制类型转换必须在this
上,而不是在that
上,以便编译器可以根据类型生成正确的指针调整。
不过,使用void*
是有问题的-您可能想使用一些不太通用且容易出错的东西。
答案 1 :(得分:1)
假设void*
约束来自您的GUI框架(这很常见,并且有一些充分的理由),实际上我很想采取一种完全不同的方法,例如让这些对象包含一些伪-唯一的“ ID”。
您可以通过简单地对构造上的static
“下一个ID计数器”进行递增和评估来生成此值。然后,您所需要做的就是比较ID,并且完全不进行指针比较。
您的“下一个ID计数器”最终会环绕起来,但是在程序的生命周期中您是否将要拥有9,223,372,036,854,775,807个按钮?可能不是。
但是,如果您要有许多这样的对象,而新成员占用的额外空间是个问题,那么您可以依靠molbdnilo显示的内容。