cpp学习之类的知识

本篇章是学习cartographer源码所遇到的不会。
1 Node类

class Node {
 public:
  Node(const NodeOptions& node_options,
       std::unique_ptr<cartographer::mapping::MapBuilderInterface> map_builder,
       //collect_metrics为false
       tf2_ros::Buffer* tf_buffer, bool collect_metrics);
  ~Node();
  // c++11: =delete: 禁止编译器自动生成默认函数; =default: 要求编译器生成一个默认函数
    Node(const Node&) = delete;
  // 禁止编译器自动生成 默认赋值函数
    Node& operator=(const Node&) = delete;

2 禁止编译器自动生成默认函数
这个是什么意思,也就是说是禁止编译器自动生成 默认拷贝构造函数(复制构造函数)
下面就以举例子的形式理解,假设存在一个MyClass 类,其声明如下

    class MyClass {
public:
    // 拷贝构造函数
    MyClass(const MyClass& other) {
        // 在这里实现将 other 的属性和值复制给当前对象的操作
    }
};

下面配合注释来理解
MyClass obj1; // 创建 MyClass 对象 obj1
MyClass obj2(obj1); // 使用拷贝构造函数,将 obj1 的值复制给 obj2,得到一个新的对象 obj2
但是,如果拷贝构造函数被删除,上述的操作将不再允许。
也就是说,你不能通过拷贝构造函数来创建新对象,类似于 MyClass obj2(obj1); 这样的语句会导致编译错误。
3 禁止编译器自动生成 默认赋值函数
这个又是什么意思,也就是说 当一个类的赋值操作符被删除后,你就无法使用赋值操作符将一个对象的值赋给另一个对象。
下面举一个简单的例子来说明:

class MyClass {
public:
    int value;

    // 删除赋值操作符
    MyClass& operator=(const MyClass&) = delete;

    // 构造函数
    接受一个整数参数 val。构造函数使用成员初始化列表来初始化类的成员变量 value,将参数 val 的值赋给 value。
    MyClass(int val) : value(val) {}
};

int main() {
    MyClass obj1(42);  // 创建 MyClass 对象 obj1,并初始化 value 为 42
    MyClass obj2(99);  // 创建 MyClass 对象 obj2,并初始化 value 为 99

    // 使用赋值操作符,将 obj1 的值赋值给 obj2
    // 但由于赋值操作符被删除,这行代码会导致编译错误
    obj2 = obj1;

    return 0;
}

在上述例子中,MyClass 类的赋值操作符被删除,所以在 main() 函数中的 obj2 = obj1;
这行代码会导致编译错误。因为赋值操作符被删除,你无法通过赋值操作符将一个 MyClass 对象的值赋给另一个对象。

4 const的理解
假设有一个函数声明如下所示:

  std::vector<
      std::set<::cartographer::mapping::TrajectoryBuilderInterface::SensorId>>
  ComputeDefaultSensorIdsForMultipleBags(
    // 第一个const 表示常量引用 表示在函数体中不能修改该参数
    // 第二个const 不能修改Node的成员函数如Subscriber
      const std::vector<TrajectoryOptions>& bags_options) const;

第一个const 很容易理解 就是表示在函数体中不能修改该参数,第二个const 是放在了函数声明的最后,这个函数一般是指类的成员函数,这个const则是表示不能通过该函数来修改类的成员变量,同样下面配合上例子来理解:

#include <iostream>

class MyClass {
public:
    MyClass(int val) : value(val) {}

    // 常量成员函数,不修改成员变量
    void PrintValue() const {
        // value = 10; // 错误:不能在常量成员函数中修改成员变量
        std::cout << "Value: " << value << std::endl;
    }

    int GetValue() const {
        return value;
    }

private:
    int value;
};

int main() {
    const MyClass obj(5);

    obj.PrintValue(); // 输出:Value: 5

    // 常量对象只能调用常量成员函数
    int value = obj.GetValue();
    std::cout << "Value: " << value << std::endl; // 输出:Value: 5

    return 0;
}

5 cpp常见的容器
继续看上面的函数

  std::vector<
      std::set<::cartographer::mapping::TrajectoryBuilderInterface::SensorId>>
  ComputeDefaultSensorIdsForMultipleBags(
    // 第一个const 表示常量引用 表示在函数体中不能修改该参数
    // 第二个const 不能修改Node的成员函数如Subscriber
      const std::vector<TrajectoryOptions>& bags_options) const;

可以看到函数的返回类型为 std::vector<
std::set<::cartographer::mapping::TrajectoryBuilderInterface::SensorId>>
首先创建了std::vector 然后vector存储的数据类型为 std::set set中存储的类型为::cartographer::mapping::TrajectoryBuilderInterface::SensorId。可以看出carto就是数据类型也封装了好几层。
下面就开始好好介绍 vector
std::vector 是 C++ 标准库中的一个容器,用于存储动态大小的数组。它提供了许多操作来方便地管理和访问数组中的元素。
std::vector 是一个模板类,可以存储任意类型的元素,例如整数、浮点数、对象等。

std::vector<int> myVector; // 创建一个空的整数向量
myVector.push_back(10); // 在向量末尾添加元素 10
myVector.push_back(20); // 在向量末尾添加元素 20
myVector.push_back(30); // 在向量末尾添加元素 30

int element = myVector[0]; // 访问第一个元素,值为 10
int anotherElement = myVector.at(1); // 使用 at() 函数访问第二个元素,值为 20

int size = myVector.size(); // 获取向量中元素的数量,此处 size 的值为 3

for (int i = 0; i < myVector.size(); ++i) {
  std::cout << myVector[i] << " ";
}
// 输出:10 20 30

接下来是set的介绍
std::set 是 C++ 标准库中的一个容器,用于存储一组不重复的元素,并且以有序的方式进行存储。它是一个关联容器,底层实现是红黑树(Red-Black Tree)。
std::set 的特点是:
存储的元素是唯一的,即不允许重复的元素。
插入、查找、删除操作的平均时间复杂度为 O(log n),其中 n 是集合中元素的个数。
下面是一个简单的例子,演示如何使用 std::set:

#include <iostream>
#include <set>

int main() {
    // 创建一个 std::set 来存储整数
    std::set<int> mySet;

    // 插入元素
    mySet.insert(5);
    mySet.insert(2);
    mySet.insert(8);
    mySet.insert(2); // 不允许重复,这个元素不会被插入

    // 使用迭代器遍历元素并输出
    std::cout << "Set elements: ";
    for (auto it = mySet.begin(); it != mySet.end(); ++it) {
        std::cout << *it << " ";
    }
    std::cout << std::endl;

    // 查找元素
    int searchElement = 8;
    auto it = mySet.find(searchElement);
    if (it != mySet.end()) {
        std::cout << "Element " << searchElement << " found in the set." << std::endl;
    } else {
        std::cout << "Element " << searchElement << " not found in the set." << std::endl;
    }

    // 删除元素
    int deleteElement = 2;
    mySet.erase(deleteElement);

    // 再次遍历输出
    std::cout << "After erasing element " << deleteElement << ": ";
    for (auto it = mySet.begin(); it != mySet.end(); ++it) {
        std::cout << *it << " ";
    }
    std::cout << std::endl;

    return 0;
}

输出结果:

Set elements: 2 5 8 
Element 8 found in the set.
After erasing element 2: 5 8 

6 cpp的新认识
结构体也有构造函数 ,例如

  struct TrajectorySensorSamplers {
    // 结构体的构造函数 使用初始化列表形式初始化其成员变量
    TrajectorySensorSamplers(const double rangefinder_sampling_ratio,
                             const double odometry_sampling_ratio,
                             const double fixed_frame_pose_sampling_ratio,
                             const double imu_sampling_ratio,
                             const double landmark_sampling_ratio)
        : rangefinder_sampler(rangefinder_sampling_ratio),
          odometry_sampler(odometry_sampling_ratio),
          fixed_frame_pose_sampler(fixed_frame_pose_sampling_ratio),
          imu_sampler(imu_sampling_ratio),
          landmark_sampler(landmark_sampling_ratio) {}

    ::cartographer::common::FixedRatioSampler rangefinder_sampler;
    ::cartographer::common::FixedRatioSampler odometry_sampler;
    ::cartographer::common::FixedRatioSampler fixed_frame_pose_sampler;
    ::cartographer::common::FixedRatioSampler imu_sampler;
    ::cartographer::common::FixedRatioSampler landmark_sampler;
  };

7 map容器
std::map 是 C++ 标准库中的一个关联容器,它提供了一种键-值(key-value)对的存储方式。std::map 中的元素是按照键的顺序自动排序的,通常是按照键的升序排列。每个键只能在 std::map 中出现一次,因为键是唯一的。

std::map 的特点包括:

关联性:std::map 中的元素是通过键关联的,每个元素都有一个唯一的键。
排序:std::map 中的元素按照键的顺序自动排序,默认情况下是按照键的升序排列。
唯一性:std::map 中的键是唯一的,每个键只能在 std::map 中出现一次。
动态大小:std::map 的大小是动态变化的,可以根据需要插入或删除元素。
下面以一个例子来说明

#include <iostream>
#include <map>

int main() {
    std::map<std::string, int> myMap;

    // 向map中插入键值对
    myMap["Alice"] = 25;
    myMap["Bob"] = 30;
    myMap["Charlie"] = 22;

    // 使用迭代器遍历map中的元素
    for (const auto& pair : myMap) {
        std::cout << pair.first << ": " << pair.second << std::endl;
    }

    // 使用operator[]访问特定键的值
    std::cout << "Alice's age: " << myMap["Alice"] << std::endl;

    return 0;
}

Alice: 25
Bob: 30
Charlie: 22
Alice's age: 25

请注意,当使用 operator[] 访问一个不存在的键时,std::map 会自动创建该键并将其值初始化为默认值。在上面的例子中,如果尝试访问一个不存在的键,例如 myMap[“David”],则会自动在 std::map 中创建一个键为 “David” 的键值对,并将值初始化为 int 类型的默认值 0。
8 boost::function函数的介绍

boost::function<void(const typename MessageType::ConstPtr&)> 是一个 Boost C++ 库中的函数对象,用于封装可调用对象(例如函数指针、函数对象、Lambda 表达式等)。在这里,它表示一个可以接受一个 const typename MessageType::ConstPtr& 类型的参数并且返回 void 的函数对象。
9 count 的认识

count 是一个 std::map 容器的成员函数,用于返回指定键在容器中的出现次数(即对应元素的个数)。对于 std::map 容器,由于其键是唯一的,因此 count 方法的返回值实际上只能是0或1。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值