如何获取实例的所有“ this”的数组

时间:2018-12-13 10:23:19

标签: c++ inheritance

假设单击“按钮”,将触发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与所有指针进行比较。

2 个答案:

答案 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显示的内容。