从std:string派生以添加typedefs和enum
Derive from std:string to add typedefs and enums
对于在客户端和服务器之间交换的UDP包,我希望支持两种字符串字段:
名为cstring
的以null结尾的c字符串
uint8_t
大小字段名为vstring
的字符串为了对包的布局进行自我文档化,我想使用简单的结构声明:
struct ABC {
vstring a;
cstring b;
}
并在反序列化函数中调用重载函数get(char*, vstring& v)
和get(char*, cstring&)
,如下所示:
void deserialize(const char* bytes, ABC& msg) {
get(msg.a);
get(msg.b);
}
void serialize(char* bytes, const ABC& msg) {
put(msg.a);
put(msg.b);
}
然而,对于用户来说,理想情况下vstring
和cstring
的行为应该与正常的std::string
一样。
我的第一个想法是简单地将std::string
作为vstring
和cstring
的公共基础,这样这两个类在过载解决过程中可以不区分,但对用户来说行为相同。但由于不鼓励从std::string
派生,我不确定该怎么办。
从std::string
派生的危险在于析构函数不是虚拟的,所以有人可能会这样做:
std::string* p = new vstring;
delete p;
你会有不明确的行为。如果你认为这样的代码不可能在你的环境/系统中编写,那就把自己打掉,从std::string
派生出来。
指导方针:
如果
vstring
和cstring
类只在非常有限的受控环境中使用,最好是由一个或少数开发人员使用,您可以与他们沟通预期的使用情况并监控实际的使用情况,或者很明显动态分配和多态性不会被滥用来处理它们,这一切都很好。另一个极端是,如果它们在你的接口中,指向数量不详的不受控制的代码,甚至不可能通知所有潜在的客户端开发人员这个问题,这是不好的,在这种情况下,你应该不喜欢从没有虚拟析构函数的类型派生。
也就是说,你真的需要在类型中编码串行化风格吗?无论如何,他们都必须编写串行化和去串行化例程,列出要串行化的字段,并且他们还可以在其中指定格式(NUL终止与长度前缀或其他任何格式)。
从思想上讲,序列化的方式不应该影响数据的类型,所以我最好这样做:
void serializeNullTerminated(char* bytes, const std::string& msg);
void deserializeNullTerminated(const char* bytes, std::string& msg);
void serializeWithSize(char* bytes, const std::string& msg);
void deserializeWithSize(const char* bytes, std::string& msg);
或者向函数传递一个附加参数:
void serialize(SerializationType st, char* bytes, const std::string& msg);
void deserialize(SerializationType st, const char* bytes, std::string& msg);
或者你可以让它们成为模板:
template<SerializationType st>
void serialize(char* bytes, const std::string& msg);
template<SerializationType st>
void deserialize(const char* bytes, std::string& msg);
关键是,用户不必处理不同类型的字符串,在他们的代码中,他们只需要选择序列化/反序列化的方式。
您必须将计算与消息解耦。因此,在您的程序中,您使用std::string
,当您需要发送/接收字符串时,您会传递符合您的协议的消息。
因此,你的库/应用程序/任何东西的唯一公共接口应该是这样的:
int send_message(std::string const &s, int mode, ... destination ... etc);
int receive_message(std::string &s, int mode, ... source ... etc);
(对于s
,char *c
可能过载(空终止))。
其中模式是标志CCD_ 20或CCD_。
内部发送/接收:
- 一个以null结尾的字符向量或
- 字符的大小,然后是矢量
您甚至不需要为cstring
和vstring
创建类。
- 将成员变量添加到共享库中的类中,不会破坏二进制兼容性吗
- 如何在C++中从两个单独的for循环中添加两个数组
- POCO::PostgreSQL:如何将std::vector支持添加到`Binder::bind`
- 如何仅为一个函数添加延迟
- 如何防止 c++ 在从浮点型转换为双精度型(不适用于 IO)时添加额外的小数?
- 使用std::transform将一个范围的元素添加到另一个范围中
- 如何将更多文件夹添加到c++include路径
- 如何将元素添加到数组的线程安全函数?
- QT通过C++添加映射QML项目
- 如何将点击的信号和插槽添加到qt中的自定义按钮中
- 如何使用重载的相等(==)运算符向测试用例添加描述
- 为什么Mat类的两个对象可以在不重载运算符+的情况下添加
- 如何防止clang格式在流运算符调用之间添加换行符<<
- 只能向C++添加一定数量的字符
- Qt和C++:将QLineEdit添加到QTabWidget中
- 将QIcon添加到QTableView单元格
- 为什么我必须在C++中添加一个赋值符号来声明一个数组
- 为什么除非添加括号,否则构造函数上的模板替换会失败?
- 将图像添加到资源文件夹UWP C++
- 从std:string派生以添加typedefs和enum