一、代码


在正式阅读APM源码之前,了解C++的基础语法是必须的。以下抽取 AP_InertialSensor.h 文件的部分内容,以此说明C++基本语法。

class AP_InertialSensor : AP_AccelCal_Client
{friend class AP_InertialSensor_Backend;public:AP_InertialSensor();/* Do not allow copies */AP_InertialSensor(const AP_InertialSensor &other) = delete;AP_InertialSensor &operator=(const AP_InertialSensor&) = delete;static AP_InertialSensor *get_singleton();enum Gyro_Calibration_Timing {GYRO_CAL_NEVER = 0,GYRO_CAL_STARTUP_ONLY = 1};void init(uint16_t sample_rate_hz);const Vector3f     &get_gyro(uint8_t i) const { return _gyro[i]; }const Vector3f     &get_gyro(void) const { return get_gyro(_primary_gyro); }Gyro_Calibration_Timing gyro_calibration_timing();static const struct AP_Param::GroupInfo var_info[];AuxiliaryBus *get_auxiliary_bus(int16_t backend_id, uint8_t instance);class BatchSampler {public:...private:...};BatchSampler batchsampler{*this};private:void _start_backends();static AP_InertialSensor *_singleton;struct {float delta_time;} _hil {};
};namespace AP {AP_InertialSensor &ins();
};

以下分成几个小段,依次解释。


二、语法解释


class AP_InertialSensor : AP_AccelCal_Client
  1. 定义了一个类 AP_InertialSensor;
  2. AP_InertialSensor继承了AP_AccelCal_Client,且是私有继承。
    C++默认的继承为私有继承,如果是公有继承应改为 class AP_InertialSensor : public AP_AccelCal_Client
    也可以说,AP_AccelCal_Client派生了一个类 AP_InertialSensorAP_AccelCal_Client叫做基类,AP_InertialSensor叫做派生类。

派生类对象存储了基类的数据成员(派生类继承了基类的实现)
派生类对象可以使用基类的方法(派生类继承了基类的接口)
派生类需要自己的构造函数
派生类可以添加额外的数据成员和成员函数
派生类不能直接访问基类的私有成员,只能通过基类的方法进行访问

friend class AP_InertialSensor_Backend;
  1. 定义了类 AP_InertialSensor 的一个友元类 AP_InertialSensor_Backend

友元类的成员函数可以访问原始类的私有成员和保护成员

public:AP_InertialSensor();/* Do not allow copies */AP_InertialSensor(const AP_InertialSensor &other) = delete;AP_InertialSensor &operator=(const AP_InertialSensor&) = delete;
  1. 定义默认构造函数 AP_InertialSensor(),通过函数重载,定义另外两个非默认的构造函数。

构造函数是一种特殊的类成员函数,在创建类对象时被调用,构造函数没有类型声明
构造函数的名称与类名相同,但通过函数重载,可以创建多个同名的构造函数
如果只有默认构造函数,可省略。如果定义非默认的构造函数,则必须定义默认构造函数
通常,构造函数用于初始化类对象的成员,初始化应与构造函数的参数列表匹配

  1. =delete 表示对于函数 AP_InertialSensor(const AP_InertialSensor &other),传入参数时该函数被删除。换句话说,敲黑板强调了,不能使用AP_InertialSensor(const AP_InertialSensor &other) 这个函数。同理,后面一句是不允许使用 =AP_InertialSensor 实例进行复制。
public:static AP_InertialSensor *get_singleton();
private:static AP_InertialSensor *_singleton;
  1. 定义一个 static类(静态类)成员函数 get_singleton(),返回数据类型为AP_InertialSensor类的指针。
  2. 定义一个指针类型的静态类成员 _singleton

静态类成员被所有对象共享,不会随着实例化新的对象而被复制
静态类成员须在类外初始化

静态成员函数属于类,不属于对象,是类域中的全局函数
静态成员函数被类、对象及类的派生类对象所共享
静态成员函数只能调用静态成员,不能调用非静态成员

    void init(uint16_t sample_rate_hz);
  1. 一句很普通的函数声明
    const Vector3f     &get_gyro(uint8_t i) const { return _gyro[i]; }
  1. 声明一个叫做 get_gyro 的函数,返回是对类成员_gyro[i]的引用。引用不会产生新的副本,也就是直接返回每个对象的_gyro[i],不会被复制。
  2. 后面的 const 说明该函数不可修改类成员_gyro[i]的值,前面的 const 说明返回值也是const,即返回值也不可修改。简单说,这是一个“只读”函数。、
  3. 该函数还是一个隐式内联函数,也就是在类内定义,但没用inline显示声明。
    enum Gyro_Calibration_Timing {GYRO_CAL_NEVER = 0,GYRO_CAL_STARTUP_ONLY = 1};Gyro_Calibration_Timing gyro_calibration_timing();
  1. 在类里定义了一个枚举类型 Gyro_Calibration_Timing
  2. 定义了一个返回类型为枚举变量的函数。实际上,返回值将是GYRO_CAL_NEVERGYRO_CAL_STARTUP_ONLY,也就是 0 或 1。
    static const struct AP_Param::GroupInfo var_info[];
  1. 这里,AP_Param是一个类,GroupInfo是一个结构体,定义了一个数组 var_info。这里并没有指明数组var_info的长度,因此这是一个动态数组,也就是后面会使用 newdelete来进行动态内存分配。静态数据需要指明数组长度。
  2. 返回类型中,static说明var_info是一个静态成员,该类的所有实例共同拥有该变量,而不是每个对象复制一份。const说明该类的每个对象都不可以修改var_info的值。总结起来,var_info是一个只能初始化一次而不可再被修改的全局变量。
    AuxiliaryBus *get_auxiliary_bus(int16_t backend_id, uint8_t instance);
  1. 该函数返回一个指针变量。问题是什么时候使用指针什么时候使用引用?

参考链接:https://blog.csdn.net/hbtj_1216/article/details/56843014
如果数据对象是数组,则使用指向const的指针
如果数据对象是类对象,则使用const引用,传递类对象参数的标准方式是按引用传递
如果数据对象是较大的结构,则使用const指针或者const引用,以提高程序的效率

    class BatchSampler {public:...private:...};BatchSampler batchsampler{*this};
  1. 在原来的类AP_InertialSensor中嵌套一个类BatchSampler
  2. BatchSampler 实例化了一个对象 batchsampler,大括号和圆括号的意思是一样的,都是表示初始化。*this表示传值,this指向BatchSampler的构造函数。

参考链接:https://bbs.csdn.net/topics/394335237
大括号是C++11后的统一初始化对象的一种方式,C++98年代是圆括号和大括号混用的,后来标准委员会的那帮大佬开会讨论后觉得这样不好,就统一都可以用大括号初始化了

private:void _start_backends();static AP_InertialSensor *_singleton;struct {float delta_time;} _hil {};
  1. private表示成员及方法只能通过类AP_InertialSensor的方法进行赋值与调用。
namespace AP {AP_InertialSensor &ins();
}
  1. 自定义了一个命名空间,名叫AP
  2. AP_InertialSensor &ins();不是很清楚,求高见!

参考链接:https://blog.csdn.net/weixin_43796685/article/details/101391950
用户或者C++本身定义了命名空间后,在该命名空间中也是一个独立的作用域,可以和其他作用域中存在相同名称的变量和函数。

— 完 —

APM(三):C++基础知识相关推荐

  1. 串口发送tcp数据 源端口号_三分钟基础知识:用动画给面试官解释 TCP 三次握手过程...

    作者 |  小鹿 来源 |  小鹿动画学编程 写在前边 TCP 三次握手过程对于面试是必考的一个,所以不但要掌握 TCP 整个握手的过程,其中有些小细节也更受到面试官的青睐. 对于这部分掌握以及 TC ...

  2. [Java面试三]JavaWeb基础知识总结.

    [Java面试三]JavaWeb基础知识总结. 1.web服务器与HTTP协议 Web服务器 l WEB,在英语中web即表示网页的意思,它用于表示Internet主机上供外界访问的资源. l Int ...

  3. 【练习题】心田花开:三年级基础知识+写作练习

    学好语文打好基础很重要,多做多练也必不可少,三年级对于孩子们来说无疑是学习的分水岭,这时候就要更加注重语文知识的学习,心田花开整合了三年级语文基础+写作的练习题,为孩子们提升语文成绩贡献一份力. 一. ...

  4. 数据库系统概论第三单元基础知识(一)

    mysql基础操作 mysql8.0 workbench /* ----------------------------基础知识------------------------------ */ # ...

  5. Kinect for Windows SDK开发入门(三):基础知识 下

    原文来自:http://www.cnblogs.com/yangecnu/archive/2012/04/02/KinectSDK_Application_Fundamentals_Part2.htm ...

  6. 初学python类必须要知道的三个基础知识(入门理解)

    一. 为什么要用到类: 类是一种更高级的封装,可以将多个功能函数按照一定的顺序组织成新的结构,这个结构有几个主要作用: 1.将复杂的组织功能装成一个整体,降低了代码使用的复杂度.外界可以直接使用而不用 ...

  7. python第三项基础知识_Python学习心得——基础知识(三)

    一.常见的Python种类 1.Cpython 使用C语言实现,Python的官方版本,CPython实现会将源文件(py文件)转换成字节码文件(pyc文件),然后运行在Python虚拟机上.我们目前 ...

  8. Elasticsearch笔记(三)基础知识

    Elasticsearch笔记(二)安装与使用 理论知识 索引.文档.节点.分片 索引.文档偏向开发人员 节点.分片偏向运维人员 文档(Document) 简介 Elasticsearch是面向文档的 ...

  9. [Windows驱动开发](三)基础知识——驱动例程

    一.NT式驱动的基本例程 1. 驱动入口函数--DriverEntry [cpp] view plaincopy // 驱动程序的一般性定义 NTSTATUS DriverEntry(IN PDRIV ...

  10. 软路由(openwrt)的三个基础知识

    openwrt的分支 openwrt openwrt是openwrt的主分支,其官网是:https://openwrt.org/ 默认官方提供的系统镜像功能比较少,基本上只提供了路由器基本功能:如果需 ...

最新文章

  1. java递归获取文件名_递归打印文件名
  2. Mac OS X 10.9.3 Beta 8升级教程
  3. MariaDB Galera 集群安装配置
  4. 学python需要什么基础知识-学习Python需要知道哪些基础入门知识?
  5. 设计模式(一)工厂模式Factory(创建型)
  6. go应用程序写kafka阻塞(大坑)
  7. 小学奥数 7834 分成互质组 python
  8. 小鹏汽车创始人何小鹏:做梦梦到投资人要投资
  9. linux 文件权限 rwt,Linux下修改文件权限(所有权)
  10. wps 选择 高亮_简单实用:一组WPS表格技巧
  11. 原生js实现吸顶导航和回到顶部特效
  12. 数据分析方法论(6种方法,8个思路)
  13. matlab norm函数_机器人手眼标定MATLAB及C++实现(二十九)
  14. vue 自定义 文字背景
  15. socket网络编程 poll的简单用法
  16. 重启计算机后回收站,电脑回收站文件被清空了该如何恢复
  17. 包看包会的变量与数据类型
  18. 计算机网络 路由器的端口ip,给路由器的一个接口上配置两个IP地址
  19. android设置图片亮度分10档,批处理图片同时调整图片亮度批处理图的大小压缩图片裁边(6页)-原创力文档...
  20. OpenVINO™基于人脸landmark检测实现眼睛疲劳/睡意检测

热门文章

  1. TortoiseGit GitLab使用教程
  2. vue动态组件的实现和传值
  3. UNcrackable-Level1绕过root检测
  4. java linkq,TongLinkQ使用
  5. 懒汉模式在多线程中的问题
  6. AES128加解密流程详细介绍
  7. C++ int128
  8. 添加新的iconfont图标的方法(看了就会)
  9. python操作networkx
  10. E680i 不用刷机的Telnet 方法