了解发送方对象类型的最佳方法是什么

What is best way to know type of sender object?

本文关键字:类型 最佳 方法 是什么 对象 方对象 了解      更新时间:2023-10-16

我有类的层次结构:

class A
{
};
class B : public A
{
};
class C : public B
{
};
class D : public A
{
};

我有一些功能,它执行通知:

void notify(A* sender, const NotificationType notification)
{
}

我的问题是如何找出发送者对象的确切类型。我想找到一种优雅的方法来解决这个问题。我不喜欢将动态转换用于这些目的。可能的方法是在类A中定义枚举,如:

enum ClassType
{
    CLASS_A,
    CLASS_B,
    CLASS_C,
    CLASS_D
};

以及定义虚拟方法:

virtual ClassType get_type(void) const;

但是这种方法的可扩展性很差。另一种将这些信息保存在NotificationType中的方法,但它的可扩展性也很差。

附言:我只想使用类似的代码:

我想使用类似的代码:

void notify(A* sender, const NotificationType notification)
{
    if (sender is object of A)
       new GuiA();
    else if (sender is object of B)
       new GuiB();
    else if (sender is object of C)
       new GuiC();
    else 
       new GuiD();
}

要根据sender的具体类型创建匹配的GUI对象,可以在A中将工厂传递给某种工厂方法。

class A
{
public: 
    virtual Agui* createGui(GuiFactory& fac) = 0;
};
class GuiFactory
{
public: 
    virtual Agui* forB(B&) = 0;
    virtual Agui* forC(B&) = 0;
    virtual Agui* forD(D&) = 0;
};
class B : public A
{
public: 
    Agui* createGui(GuiFactory& fac)
    {
        return fac.forB(*this);
    }
};
void notify(A* sender, const NotificationType notification)
{
    // Use A interface...
    // Get the concrete GuiFactory from somewhere, and use it
    auto gui = sender->createGui(win32GuiFactory);
}

如果你想知道类型来持久化你的层次结构,可以考虑使用boost::TypeIndex(http://www.boost.org/doc/libs/develop/doc/html/boost_typeindex.html)。

如果你想知道类型以不同的方式处理不同的类型,可以考虑使用Visitor代替类型标识符,或者使用虚拟函数制作抽象接口来满足你的需求。

已编辑

您的目标是为不同的类型创建不同的UI对象。您可以使用以下模型来达到您的目标:

class UIObject {...};
class UIObjectFactory {...};
class A {
public:
   virtual std::unique_ptr<UIObject> Create(UIObjectFactory& factory) = 0;
};
void OnNotify(A* sender) {
    auto ptr = sender->Create(GetUIFactory());
    ...
}

以及定义虚拟方法:

virtual ClassType get_type(void) const;

实现这一点并消除可伸缩性问题的最简单方法是在每个类ABC…中实现get_type()成员函数。。。这边:

typedef uintptr_t ClassType;
virtual ClassType get_type() const
{
    static int dummy;
    return reinterpret_cast<ClassType>(&dummy);
}

将为添加此成员函数的每个类创建一个静态变量dummy,以便返回值唯一标识该类。