ROS 包的所有代码都应定义在以包命名的命名空间中。为了将生成的代码与包中的其他代码分开,它在子命名空间中定义:
::msg .::srv .注意:使用额外的子命名空间可确保符号不同且不与 ROS 1 符号重叠。这允许将两者都包含在像 ros1_bridge 这样的单个编译单元中。
遵循 ROS 2 的 C++ 风格指南,命名空间层次结构映射到文件夹结构。文件名使用带有下划线的小写字母数字字符来分隔单词,并以 .hpp 或 .cpp 结尾。
对于消息,会生成一个同名后跟下划线的模板化结构。单个模板参数是数据结构的分配器。
为了便于使用,有一个与消息同名的 typedef,它使用默认分配器(例如 std::allocator)。
对于每条消息,正在生成两个文件:

除了带有后缀 __struct 的文件之外,这还允许添加其他文件以提供附加功能。对于每个附加功能,可以决定从第一个头文件中包含它。
TODO: specify content of file
| ROS type | C++ type |
|---|---|
| bool | bool |
| byte | uint8_t |
| char | char |
| float32 | float |
| float64 | double |
| int8 | int8_t |
| uint8 | uint8_t |
| int16 | int16 |
| uint16 | uint16 |
| int32 | int32 |
| uint32 | uint32 |
| int64 | int64 |
| uint64 | uint64_t |
| string | std::string |
| ROS type | C++ type |
|---|---|
| static array | std::array |
| unbounded dynamic array | std::vector |
| bounded dynamic array | custom_class |
| bounded string | std::string |
该结构对消息的每个字段都有同名的公共成员变量。对于每个字段,都会创建一个 typedef,它以具有前导下划线和尾随 _type 的成员命名。
数值常量被定义为结构中的枚举。
所有其他常量在结构中声明为静态 const 成员,并且它们的值在结构之外定义。
这里的默认指定:
在下面的讨论中,“member”指的是 C++ 类中的类成员,而“field”指的是 IDL 文件中的字段定义。
默认构造函数使用 IDL 文件中指定的默认值初始化所有成员,或者使用本文中定义的字段类型的通用默认值初始化所有成员(注意:对于 C++,char 字段被视为数字)。在某些情况下,这可能是不可取的,因为这些字段通常会立即被用户提供的值覆盖。因此,构造函数采用 rosidl_generator_cpp::MessageInitialization 类型的可选指令来控制初始化的完成方式:
可以选择使用分配器调用构造函数。
该结构没有带有成员位置参数的构造函数。这样做的简短原因是,如果代码依赖位置参数来构造数据对象,更改消息定义会以微妙的方式破坏现有代码。由于这会阻碍消息定义的演变,因此应通过单独设置成员来填充数据结构,例如使用 setter 方法。
对于每个字段,都会生成一个 setter 方法以启用方法链接。它们以带有前导集__的字段命名。 setter 方法有一个参数来传递成员变量的值。每个 setter 方法都返回结构本身。
比较运算符 == 和 != 基于每个成员执行比较。
该结构包含四种常见指针类型的 typedef,即普通指针、std::shared_ptr、std::unique_ptr、std::weak_ptr。对于每种指针类型,都有一个非常量和一个 const 类型定义:
RawPtr and ConstRawPtrSharedPtr and ConstSharedPtrUniquePtr and ConstUniquePtrWeakPtr and ConstWeakPtr为了与 ROS 1 相似,typedef Ptr 和 ConstPtr 仍然存在,但已被弃用。与 ROS 1 相比,它们使用 std::shared_ptr 而不是 Boost。
对于服务,会生成一个名称相同且后跟下划线的结构。
该结构仅包含两个 typedef:
生成的代码与消息一样被拆分到多个文件中。
对于这些服务的请求和响应,正在生成单独的消息以服务命名部分,并声明。_Request 或_Response 后缀。它们仍然在 srv 子命名空间中定义。
ROS2的C++编程,目前规范其实在发展中,不太完善,但是做为开发人员需要紧跟当前的形势,了解其发展现状。