标识继承类的最佳方法

Best way to id an inherited class

本文关键字:最佳 方法 继承 标识      更新时间:2023-10-16

我正在开发一个小框架,C++在我的一些项目中使用,作为各种实用程序库静态链接。我想你可以把它与一个更特定于我的个人需求的领域,以及像juce这样更简单的库进行比较。这和其他任何事情一样,都是一次学习和体验练习,所以我想花时间正确地做事并理解我所应用的技术。我目前正在使用 linux,但目标是代码可移植,因此这将允许我将任何特定于平台的代码写入接口。

目前,我正在开发一个基本的消息传递系统,我希望允许包含各种类型的对象的消息。我最初的想法是这样的:

class Message {
  virtual std::string type;
};
class DataMessage : Message {
  std::vector<std::string> *data;
};

我的问题是,识别消息是数据消息的最佳方法是什么,并将其转换为其实际类型,或者访问它包含的数据?

我可以像上面这样为类型使用字符串,但这并不能保证每个子类实际上都有一个唯一的类型 id。另外,我想知道字符串处理的开销是否会比替代方案慢(例如,我可以扩展枚举吗?

至于访问数据,如果我可以将消息转换为正确的类型,这不是问题。否则,我可以将虚拟函数作为访问器添加到基类中(但是如何让它使用与基类中指定的返回类型不同的返回类型?如果类不需要任何额外的数据怎么办?),或者作为作用于数据的工作函数(但我宁愿将其作为类之间的数据传递机制,而不是回调样式框架)。

任何建议,替代方案或链接将不胜感激。讨论不同的方法会很棒!

提前感谢伙计们。

我的问题是,识别消息是数据消息的最佳方法是什么,并将其转换为其实际类型,或者访问它包含的数据?

你不应该那样做!
一旦你这样做了,你就会使你的设计变得薄弱。你基本上最终打破了SOLID范式的基本原则之一,即"利斯科夫替代原理"。
请注意,如果在代码中的任何位置,如果根据对象的具体类型执行操作,则要编码到实现而不是接口。基本设计准则是:
"代码到接口而不是实现。"
如果您开始编码到具体类型,您的代码将变得更加难以维护并且更加紧密耦合。每次你想要添加新的派生类时,你的代码甚至会进一步分解,你失去了慷慨。

相反,您应该依靠多态性来为您完成任务。应在基类中实现虚拟方法,并在派生类中适当地重写它们。您只需要调用这样的方法,运行时就会在每个类中调用适当的方法,因为运行时知道具体类型是什么。重要的是,您编写的代码不需要知道类型。

您可能想查看一些好的模式,例如模板方法模式,这可能会很好地为您服务。

您可以使用

DataMessage* pDataMessage = dynamic_cast<DataMessage*>(pMessage) .仅当pMessageDataMessage对象时,pDataMessage才有效。否则将NULL.

使用 typeid 运算符。这是RTTI C++的一部分。几乎所有编译器都支持它。虽然如果这是你自己的框架,使用数据字段(更好的枚举类型)的方法也不是那么糟糕。