ROS2 中,cpp新特性的应用
auto
1
2 // auto 自动推导类型
auto a = 1; // int a = 1
智能指针
智能指针分为三种
std::shared_ptr
是一个类模板,它的对象的行为类似于指针,它可以记录共享它所管理的内存对象的对象个数。多个共享指针可以共享同一个对象,当最后一个共享指针被销毁时,会自动释放其所指向的对象。一个共享指针通常使用 make_shared<> 来创建,也可以通过拷贝或者赋值其他共享指针的方式创建。 代码示例,在 demo_one_pkg/src/ 下创建 learn_shared_ptr.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
int main(){
// 创建共享智能指针 <数据类型/类>(参数) 返回值,对应类的共享指针
auto p1 = std::make_shared<std::string>("This is a string.");
std::cout << "p1的引用计数: " << p1.use_count() << ", 指向内存地址: " << p1.get() << std::endl;
auto p2 = p1;
std::cout << "p1的引用计数: " << p1.use_count() << ", 指向内存地址: " << p1.get() << std::endl;
std::cout << "p2的引用计数: " << p2.use_count() << ", 指向内存地址: " << p2.get() << std::endl;
// 释放引用
p1.reset();
std::cout << "p1的引用计数: " << p1.use_count() << ", 指向内存地址: " << p1.get() << std::endl;
std::cout << "p2的引用计数: " << p2.use_count() << ", 指向内存地址: " << p2.get() << std::endl;
// p2->c_str() 调用成员函数
std::cout << "p2的指向内存地址数据: " << p2->c_str() << std::endl;
return 0;
}在 CMakeLists 文件中添加
1
2
3
4
5
6 # 添加可执行文件
add_executable(learn_shared_ptr src/learn_shared_ptr.cpp)
# 拷贝节点到install
install(TARGETS demo_one_node person_node learn_shared_ptr
DESTINATION lib/${PROJECT_NAME}
)编译并执行
1
2
3 colcon build
source install/setup.bash
ros2 run demo_one_pkg learn_shared_ptr
Lambda 表达式
可以利用它来编写内嵌的匿名函数,用以替换独立函数或函数对象。
代码示例,在 demo_one_pkg/src/ 下创建 learn_lambda.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
int main(){
// [] 是捕获参数列表,() 中放置参数,{} 中是函数体, -> 后面是返回类型
auto add = [](int a, int b) -> int {return a + b;};
int sum = add(200, 50);
// 这里的 [sum] 可以替换为 [&],后者可以捕获其之前的所有参数
auto print_sum = [sum]() -> void {std::cout << sum << std::endl;};
print_sum();
return 0;
}在 CMakeLists 文件中添加
1
2
3
4
5
6 # 添加可执行文件
add_executable(learn_lambda src/learn_lambda.cpp)
# 拷贝节点到install
install(TARGETS demo_one_node person_node learn_shared_ptr learn_lambda
DESTINATION lib/${PROJECT_NAME}
)编译并执行
1
2
3 colcon build
source install/setup.bash
ros2 run demo_one_pkg learn_lambda
函数包装器
cpp 中函数可大致分为三类,一类是自由函数,一类是成员函数,另外一类就是 Lambda函数。三种函数的调用方式不同,自由函数直接函数名加参数调用,成员函数需要对象来调用。函数包装器就是用于统一这三种函数的调用方式的。
代码示例,在 demo_one_pkg/src/ 下创建 learn_functional.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
// 自由函数
void save_with_free_fun(const std::string & file_name){
std::cout << "自由函数: " << file_name << std::endl;
}
class FileSave{
private:
public:
FileSave() = default;
~FileSave() = default;
// 成员函数
void save_with_member_fun(const std::string & file_name){
std::cout << "成员函数: " << file_name << std::endl;
};
};
int main(){
FileSave file_save;
// Lambda 函数
auto save_with_lambda_fun = [](const std::string & file_name) -> void {std::cout << "Lambda 函数: " << file_name << std::endl;};
// 未统一调用
save_with_free_fun("file.txt");
file_save.save_with_member_fun("file.txt");
save_with_lambda_fun("file.txt");
// 使用函数包装器统一调用
std::function<void(const std::string&)>save1 = save_with_free_fun;
// 成员函数放入包装器较为复杂,涉及三个参数
std::function<void(const std::string&)>save2 = std::bind(&FileSave::save_with_member_fun, &file_save, std::placeholders::_1);
std::function<void(const std::string&)>save3 = save_with_lambda_fun;
// 调用
save1("file.txt");
save2("file.txt");
save3("file.txt");
return 0;
}在 CMakeLists 文件中添加
1
2
3
4
5
6 # 添加可执行文件
add_executable(learn_functional src/learn_functional.cpp)
# 拷贝节点到install
install(TARGETS demo_one_node person_node learn_shared_ptr learn_lambda learn_functional
DESTINATION lib/${PROJECT_NAME}
)编译并执行
1
2
3 colcon build
source install/setup.bash
ros2 run demo_one_pkg learn_functional