源码阅读笔记

rplidar_ros的源码

1、pragma pack(1)的作用:以1个字节对齐

#include <cstdio>

#pragma pack(push)   //保持对齐状态

#pragma pack(1)   //设定结构体s强制一个字节对齐
struct s {
    char ch;
    int i;
};
#pragma pack(pop)    //恢复对齐状态

int main()
{
    printf("%d", sizeof(struct s));
    return 0;
}

 

不加pragma语句时,输出为8,结构体以int的4字节对齐;如果加上pragma pack(1)后,以1个字节对齐,这样强制将数据连续。

 

2、双下划线的含义:

双下划线(__) 开头表明是编译器的变量

所以 双下划线__只是C语言的一个合法标识符
不一定是变量, 也可以是函数,宏等。

同时双下划线(__)多用于告警提示:

FILE 包含当前程序文件名的字符串
LINE 表示当前行号的整数
DATE 包含当前日期的字符串
STDC 如果编译器遵循ANSI C标准,它就是个非零值
TIME 包含当前时间的字符串

#include <cstdio>

int main()
{
    printf("file name is %s\n", __FILE__);   //文件名
    printf("line is %d\n", __LINE__);        //行号

    printf("date is %s\n", __DATE__);        //日期
    printf("time is %d\n", __TIME__);        //时间

    return 0;
}

输出

 

3、#pragma once

 为了避免同一个文件被include多次,C/C++中有两种方式,一种是#ifndef方式,一种是#pragma once方式。

区别:声明方式不一样

 #ifndef __SOMEFILE_H__
 #define __SOMEFILE_H__
 ... ... // 声明、定义语句
 #endif
    #pragma once
    ... ... // 声明、定义语句

大型工程里,#ifndef方式耗时更多

编译器支持上,#ifndef在所有支持c++编译的编译器都是可用的,而#pragma once有限制

在include的内容上,#ifndef可以包含部分#include(针对不同平台选择不同的库函数),而#pragma once是针对整个include文件

 

4、纯虚函数

含有纯虚拟函数的类称为抽象类,它不能生成对象。

在很多情况下,基类本身生成对象是不合情理的。例如,动物作为一个基类可以派生出老虎、孔雀等子类,但动物本身生成对象明显不合常理,因为动物作为一种从实例中抽象出的概念。

#include<iostream>
using namespace std;

class Base
{
public:
    virtual void print() = 0;
    virtual void play() {
        cout << "Base play!" << endl;
    }
    virtual ~Base(){}
};

class Derived : public Base{
public:
virtual void print(){
    cout << "Derived print!" << endl;
}
virtual void play(){
    cout << "Derived play!" << endl;
}
};

int main(){
    Derived de;
    de.print();
    de.play();
    return 0;
}

如果直接创建Base bs;时,编译器会报错提示有virtual functions are pure within ‘Base’

 

posted @ 2021-11-01 10:51  水水滴答  阅读(40)  评论(0编辑  收藏  举报