1

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

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

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

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

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

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

非常感谢任何建议、替代方案或链接。讨论不同的方法会很棒!

提前谢谢各位。

4

3 回答 3

3

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

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

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

您可能想查看一些不错的模式,例如模板方法模式,它们可能对您很有帮助。

于 2012-06-25T04:44:27.603 回答
2

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

于 2012-06-25T04:21:50.050 回答
2

您可以使用DataMessage* pDataMessage = dynamic_cast<DataMessage*>(pMessage). pDataMessage仅当是pMessage一个DataMessage对象时才有效。否则会NULL

于 2012-06-25T04:29:42.033 回答