源码阅读笔记
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’
作者:水水滴答
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。