如何从基指针推断类的子类型

How to deduce subtype of a class from a base pointer

本文关键字:类型 指针      更新时间:2023-10-16

我有一个基类(Notification)和两个子类(WebNotification和DesktopNotification)。我从外部源接收WebNotifications和DesktopNotifications,然后我将它们作为通知指针传递给GUI实体,该实体应该根据通知的类型做不同的事情。如何根据通知*推断子类型?

我知道在Notification类中添加一个带有类型的enum可以工作,但这似乎不是一个优雅的解决方案。

我有其他选择吗?

有多种选择。

首先,专门化行为应该是类的一部分,而不是客户端的一部分。这意味着你应该避免动态检查类的类型,除非你真的被迫这样做。

这通常通过多态性实现:

class Notification {
public:
  virtual void render(UI* ui) = 0;
};
class WebNotification : public Notification {
public:
  void render(UI* ui) override {
    ....
  }
};

在某些情况下,这是不够的,所以你可以选择标记你的类,例如

class Notification {
public:
  enum class Type {
    WEB,
    DESKTOP
  };
private:
  Type type;
protected:
  Notification(Type type) : type(type) { }
public:
  Type getType() const { return type; }
};
class WebNotification : public Notification {
public:
  WebNotification() : Notification(Notification::Type::WEB) { }
};
...
Notification* notification = ...
if (notification->getType() == Notification::Type::WEB)
  ...

或者让编译器为您标记它们,但是您必须启用RTTI,有时这是不可取的:

if (dynamic_cast<WebNotification*>(notification) != null) {
  ...
}

使用动态类型转换,即

Notification* notification;
WebNotification* web_notification = dynamic_cast<WebNotification*>(notification);
    if ( web_notification != NULL ) {
    // this is a web notification;
}
DesktopNotification* dt_notification = dynamic_cast<DesktopNotification*>(notification);
if ( dt_notification != NULL ) {
    // this is a desktop notificaiton
}