- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
目前我正在使用 C++ 编写一个用于数据通信的消息类,例如通过串行端口。对于这个问题,假设我有两条不同的消息(我确实有更多),例如带有校准数据和传感器值的陀螺仪和加速度消息。由于我是一名自学 C++ 的工程师,所以我看了我最喜欢的 C++ 书籍,发现对消息使用工厂模式可能会有用。
所以我的头文件的简化版本如下所示:
#ifndef MESSAGE_H
#define MESSAGE_H
#include <cstddef>
class message
{
public:
/**
* \brief ~message:
* Virtual destructor of the class message.
*/
virtual ~message();
/**
* \brief getMessage:
* Creates a message (with new).
*
* \param[in] size Size of the dataArray.
* \param[in] data Bytearray of the message.
*
* \return If messagetype in the Array data eqal to 0 => new GyroMessage.
* If messagetype in the Array data eqal to 1 => new AccelMessage.
* Else => new NotValidMessage.
*
*/
static message* getMessage(size_t size, char* data);
protected:
/**
* \brief message:
* Default konstructor of the class message.
*
* \param[in] size Size of the dataArray.
* \param[in] data Bytearray of the message.
*
*/
message(size_t size, char* data);
/// Size of the dataArray.
int size;
/// Bytearray of the message.
char* dataArray;
/// Type of message.
char messagetype;
};
#endif // MESSAGE_H
类 GyroMessage
、AccelMessage
和 NotValidMessage
是 message
的子类。这种模式有两点我不喜欢:
首先:如果我想添加一条新消息,现在添加一个继承自 message
的新类就足够了,您必须在静态函数中添加另一个 if 语句 getMessage
.
第二:如果我想使用数据,例如从 GyroMessage
,我必须reinterpret_cast
消息。
是否有更好的模式可用于此目的?
最佳答案
我不确定我的想法是否好,但分享不需要任何费用。
我几天前为 Arduino 做了类似的事情,对于我的情况,我做出了这样的选择:
pod
(普通旧数据)结构,编译器会在其中打包它。为此,我使用了一个 define
来处理编译器指令以将其打包(对于 g++
是 __attribute__((packed))
)为了在字节数组中发送消息,我在类中使用了模板化的union
。如果使用此方法,则必须检查发送方和接收方的字节顺序。类似的东西:
template <class P>
union Packet {
P data;
unsigned char buff[sizeof(P)];
}
我的工具链支持模板,所以我使用了它们。但是您可以使用更多模板在同一个 union 中插入更多包。您只需要记住在标识包类型的所有结构中都有一个公共(public)字段(见下文)。
例子(我简化了很多):
template <class A, class B, std::size_t N>
union Packet {
A a;
B b;
unsigned char buffer[N];
};
#define PAYLOAD(X, Y) struct X \
Y __attribute__((packed)); \
typedef struct X X;
template <class A, class B, std::size_t N>
class Message {
union Packet<A, B, N> packet;
// [...]
}
// [...]
// Time to declare you messages
PAYLOAD(GyroMessage, { char type; float x; float y; })
PAYLOAD(AccelMessage, { char type; float x; float y; float z; })
// GyroMessage will always have type = 0x01 and
// AccelMessage will always have type = 0x02 for example
// you know that sizeof(AccelMessage) > sizeof(GyroMessage)
// there is for sure a way to automatize this thing at
// compilation time through macros.
// Time to declare the class
Message<GyroMessage, AccelMessage, sizeof(AccelMessage)> message;
要检索正确的值,您仍然可以(通过 union )访问所需的值,而无需添加新的特定函数。但目前我没有非常好的方式以编程方式访问它们。
那些只是一些提示,我真的不知道你在做什么或者你的优先级是什么。因此,请谨慎服用。
关于c++ - 如何在 C++ 中定义一个制作精良的消息类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46401734/
我是一名优秀的程序员,十分优秀!