了解发件人对象类型的最佳方法是什么?

时间:2016-05-11 08:13:47

标签: c++ oop

我有类的层次结构:

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中的方法,但它也具有不良的可伸缩性。

P.S。我只想使用类似的代码:

我想使用类似的代码:

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();
}

3 个答案:

答案 0 :(得分:2)

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

如果你想知道类型以不同的方式处理不同的类型,考虑使用类型标识符的访问者或使用虚拟功能的抽象界面满足您的需要。

<强> EDITED

您的目标是为不同类型创建不同的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());
    ...
}

答案 1 :(得分:2)

要根据具体类型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);
}

答案 2 :(得分:0)

  

并定义虚拟方法:

virtual ClassType get_type(void) const;

实现此目标并摆脱可扩展性问题的最简单方法是在每个类get_type()AB中实施C成员函数,...这样:

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

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