const 内联 枚举 宏
const 常量
程序运行时在常量表中,系统为它分配内存,在堆栈分配了空间;const常量有数据类型;语句末有分号;有类型检查;可以限制范围 //将所有不希望改变的变量加const修饰
const int a = 1;在类中定义并初始化const变量是不合法的
static QString CC_VERTICAL_LINE("TEX_PNG_BUHIN_01_12"); //静态变量也是只能在类中定义不能初始化
static const int a = 1;const static char *LogTag = "ScreenOff"; //只有静态const变量才可以在类中声明定义,非静态常量都只能在类中声明定义,在构造函数中初始化
普通变量可以在类中声明与定义,在构造函数中进行初始化,静态成员是"类级别的",也就是它和类的地位相同,而普通成员是"对象级别(即类的实例化级别)".类级别的成员先于该类任何对象的存在而存在,
它被该类所有对象共享,可以推测一下:现在要实例化一个对象,那么静态变量是需要包含在这个对象里的对吧,假设是实例化对象的时候才定义这个变量,那么若是此时另一个线程也要创建这个类的对象,
若假设成立,则产生问题:1. 静态变量的重复定义 2. 即使不产生重复定义,那么也会产生竞争,造成死锁,从而无法成功创建对象,所以:普通静态成员需要在类中声明与定义,在类外初始化
内联
定义:是用inline关键字修饰的函数,目的是为了消除函数调用时的时间开销,从源代码层看,内联函数它有函数的结构,而在编译后,却不具备函数的性质,内联函数不是在调用时发生控制转移,
而是在编译时将函数体嵌入在每个调用处
特点:是在被调用的地方被展开而不生成执行代码
优点:既保持预处理宏的效率又增加安全性,还能像一般成员函数一样可以在类里访问自如
条件:1.递归函数不能定义为内联函数 2. 内联函数一般适合于不存在while和switch等复杂的结构且只有1~5条语句的小函数上,否则编译系统将该函数视为普通函数
3. 内联函数只能先定义后使用,否则编译系统也会把它认为是普通函数 4. 对内联函数不能进行异常的接口声明 5. 定义了静态变量的函数不能成为内联函数
inline:函数如果定义在类中,那么会自动被认为是申请成为内联函数,如果在类外,那么需要加关键字inline对编译器进行申请,在类外定义的函数如果不加inline关键字,那么一定不是内联函数,
inline关键字是对编译器的一个申请,能不能成为内联函数,还要看编译器对该函数定义的具体处理;在类中定义的时候必须把函数体和声明结合在一起;主张所有的内联函数都定义在类外,
用inline关键字声明,这样可以减少混乱。
递归函数:如果一个函数调用了它自身,不管是直接的还是间接的,都称该函数为递归函数
例如:求一个变量val的阶乘
int factorial(int val) {
if (val > 1) { // 递归条件
return factorial(val -1)*val; //递归语句
}
else {
return 1; //递归结束条件
}
枚举
定义:枚举是C++的一种派生数据类型,它是由用户定义的若干枚举常量的集合
特点:在编译的时候确定其值,可以一次定义大量相关的常量,枚举可以被限制名字空间,类内部,值会自动加1,如果没设初值,那么会从0开始,枚举有类型,因为其存储方式与int相似,所以枚举值可以
当做int型使用,但使用时最好还是进行强制类型装换
例子:两个不同类型的枚举值之间需要先进行类型转换,再进行比较
enum Colors {Red, Green, Blue, Yellow} //枚举值的定义最好使用十六进制,因为十六进制转换为二进制会更快
(int)Colors.Red //枚举值转换为int 现在最好使用新式转换, int i = static_cast<int>(Color.Red)
枚举值可以当做int型使用,如 enum {Number = 5;} int scores[Number];
枚举在QT中的使用:
如果是使用的C++&&QML混合编程,且希望在qml中使用C++定义的枚举,需要做如下几步:
1. 在类中开始的地方用Q_ENUMS(Name)注册进QT元对象系统
2. 在构造与析构之前对枚举进行定义
之后在QML中使用的时候形式如 类名.枚举变量
宏
宏定义: 宏即宏替换,在C语言源程序中允许用一个标识符来表示一个字符串,称为宏,关键字 define,在所有使用到宏的地方都只是直接的替换而不做任何类型检查
宏替换是C提供的三种预处理功能的其中一种,这三种预处理包括:宏定义,文件包含,条件编译,C++继承C的遗产,在C++中也可以使用宏,宏不能访问对象的私有成员,
宏的定义很容易产生二义性
特点:在预处理阶段对宏定义的替换,使用时要特别小心;宏本身不占用内存单元,但每次调用都分配内存;语句的最后不加分号;无数据类型;非常量,只是盲目替换;是全局的
使用:(1) 防止头文件被重复包含
#ifndef COMDEF_H //#:字符串化运算符,在一个预处理器宏中的参数前面使用#,预处理器会把这个参数转换为一个字符数组,并把这一点与没有插入标点符号的若干个
#define COMDEF_H //字符数结合而链接成一个单独的字符数组,能够生成一个十分方便的宏用于调试期间打印出变量的值
...... //中间可以有任意个空格,串一但开始,仅由一新行结束,宏名定以后,即可成为其他宏名定义中的一部分;
#endif //宏替换仅仅是以文本串代替宏标识符,前提是宏标识符必须独立的识别出来,否则不进行替换,如果串长于一行,可以在该行末尾用反斜杠'\'续行
(2) 重新定义一些类型,防止由于各种平台和编译器的不同,而产生的类型字节数差异,方便移植
typedef unsigned char boolean; /*Boolean value type */
typedef unsigned long int uint32; /*Unsigned 32 bit value */
typedef signed char int8; /*Signed 8 bit value */
typedef signed long int int32 /*Signed 32 bit value */
(3) 得到指定地址上的一个字节或字 //为防止出现包含错误,所有的参数都要用小括号包含
#define MEM_B(x) (*((byte *)(x))) //字节
#define MEM_W(x) (*((word *)(x))) //字
(4) 求最大值和最小值
#define MAX(x, y) ((x)>(y)?):(x):(y) //最大值
#define MIN(x, y) ((x)<(y)?):(x):(y) //最小值
(5) 判断字符是不是十进制的数字
#define DECCHK(c) ((c) >='0' && (c) <= '9')
(6) 使用一些宏跟踪调试
ANSI标准说明了五个预定义的宏名:__LINE__,__FILE__,__DATE__,__TIME__,__STDC__
__LINE__:存放当前行号的整型字面值;
__FILE__:存放文件名的字符串字面值;
__DATE__:存放文件编译日期的字符串字面值
__TIME__:存放编译时间的字符串字面值
__STDC__:当要求程序严格遵循ANSI C标准时该标识被赋值为1;
__FUNCTION__ 当前所在函数名
(7) 关于#和##,#的功能是将其后面的宏参数进行字符串化操作,简单说就是对它所引用的宏变量通过替换后在其左右各加一个双引号
##被称为连接符,用来将两个Token连接为一个Token,它允许设两个标识符并把它们粘贴在一起自动产生一个新的标识符
#define COMMAND(NAME) {#NAME,NAME##_command}
例子:define FILED(a) char *a##_string; int a##_size
class Record {
FIELD(one);
FIELD(two);
FIELD(three);
...
};
每次调用FIELD()宏,将产生一个保存字符串数组的标识符和另一个保存字符数组长度的标识符,它不仅易读而且消除了编码出错,使维护更容易
#define ChECK_NULLPTR_IQA(p)\ //: \必不可少,表示一句没写完,是用来续行的
if (NULL == p) {\
NGLogDebug("IQA", "%s Memory allocation failed!", __PRETTY_FUNCTION__);\
return;\
}\
else {\
NGLogDebug("IQA", "%s Memory allocation success ! p = %p", __PRETTY_FUNCTION__, p);\
}
实际调用中会出现下面所示的替换过程
#define CHECK_NULLPTR_IQA(m_pFCSettingModel);
if (NULL == m_pFCSettingModel) {
NGLogDebug("IQA", "%s Memory allocation failed!", __PRETTY_FUNCTION__);
return;
}
else {
NGLogDebug("IQA", "%s Memory allocation success ! m_pFCSettingModel = %p", __PRETTY_FUNCTION__, m_pFCSettingModel);\
}
(8) 宏定义字符串
#define DEMO_TEST QString("Demo_Test") //定义的宏替换之后是QString类型的字符串
#define FLAG (2) //定义的FLAG替换之后就是(2),加个括号感觉不错
#define DEMO_TEST “Demo_Test” //定义的宏替换之后是std::basic类型的字符串
const 内联 枚举 宏的更多相关文章
- C++学习笔记 宏 const 内联 枚举
宏, const变量, 内联, 枚举 宏 宏定义: 宏即宏替换,在C语言源程序中允许用一个标识符来表示一个字符串,称为宏,关键字 define,在所有使用到宏的地方都只是直接的替换而不做任何类型检查 ...
- C++程序设计基础(4)宏定义和内联
1.知识点 1.1宏定义 (1)不带参数的宏定义 #define ERROR_MESSAGE -100 #define SECONDS_PER_DAY 60*60*60 (2)带参数宏定义,这种形式称 ...
- GNU C内联汇编(AT&T语法)
转:http://www.linuxso.com/linuxbiancheng/40050.html 内联汇编提供了可以在C或C++代码中创建汇编语言代码,不必连接额外的库或程序.这种方法对最终程序在 ...
- [C++] inline内联函数使用方法
C++支持内联函数,目的是为了提高函数的执行效率,类似于C语言中的宏定义 内联函数在调用时将它在程序中的每个调用点展开,不用额外分配栈空间 内联函数的定义在一个源文件中出现一次,但在多个源文件中可以同 ...
- 读书笔记 effective c++ Item 2 尽量使用const,枚举(enums),内联(inlines),不要使用宏定义(define)
这个条目叫做,尽量使用编译器而不要使用预处理器更好.#define并没有当作语言本身的一部分. 例如下面的例子: #define ASPECT_RATIO 1.653 符号名称永远不会被编译器看到.它 ...
- C++初阶(命名空间+缺省参数+const总结+引用总结+内联函数+auto关键字)
命名空间 概述 在C/C++中,变量.函数和后面要学到的类都是大量存在的,这些变量.函数和类的名称将都存在于全局作用域中,可能会导致很多冲突.使用命名空间的目的是对标识符的名称进行本地化,以避免命名冲 ...
- C++内联函数与宏定义
用内联取代宏: 1.内联可调试: 2.可进行类型安全检查或自动类型转换: 3.可访问成员变量. 另外,定义在类声明中的成员函数自动转化为内联函数. 文章(一) 内联函数与宏定义 在C中,常用预处理语句 ...
- __inline定义的内联函数和宏的区别
转自:http://blog.csdn.net/lw370481/article/details/7311668 函数与宏 #define TABLE_COMP(x) ((x)>0?(x):0) ...
- C++(十七) — 宏代码、内联函数
1.C++ 表达式返回值 返回引用:当函数返回引用类型时,没有复制返回值.相反,返回的是对象本身.(与之对应的C语言中,返回的是变量的值) C++中,表达式返回的是变量本身(也就是变量对应的地址). ...
随机推荐
- Jquery 点击事件重复获取叠加 (一)
用jquery添加绑定事件 添加多少次 点击的时候就触发多少次 如果想解决这个问题 就在点击函数里先用 $(对象).off("click") 取消上一次的点击事件 上码: $(&q ...
- hdu 6134 Battlestation Operational 莫比乌斯反演
Battlestation Operational Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 65536/65536 K (Jav ...
- win10,配置python3.6,虚拟环境
1.安装python3.6(官网下载) 2.pip install virtualenv(安装虚拟环境) 3.virtualenv TestEnv(创建名为TestEnv的虚拟环境) 4.进入Test ...
- ubuntu16系统磁盘空间/dev/vda1占用满的问题
参考文档: https://www.cnblogs.com/moonandstar08/p/6091507.html (系统磁盘空间/dev/xvda1占满原因分析) https://blog.csd ...
- webpack优化记录
什么是Webpack . ( 模块打包机,分析项目结构,找到js不能识别的代码语言,转换和打包后,供browser使用 ) WebPack可以看做是模块打包机:它做的事情是,分析你的项目结构,找到 ...
- GridView实现拖拽排序以及数据交互
在研究项目中的一个效果的时候,查找资料过程中发现有人有这么一种需求,就是GridView在实现拖拽排序的基础上,如果是两个GridView之间实现拖拽效果,并要实现数据交互. 一.效果图: 实现这个效 ...
- display: none; 与 jq show方法之间的联系
1. 定义四种常用隐藏元素的方式,然后调用 jq 的 show 方法显示,观察各原先隐藏元素的 display 表现,结合 jq 源码,show 方法设置 元素 display 属性值为 ...
- PostCSS以及cssnext语法
什么是postcss postcss 一种对css编译的工具,类似babel对js的处理,常见的功能如: 1 . 使用下一代css语法 2 . 自动补全浏览器前缀 3 . 自动把px代为转换成 rem ...
- [C#][Windows]]基于ArcFace2.0+红外双目摄像头的活体检测
废话不多说 直接上图 这个是demo中用到的双目摄像头,一个是红外的,一个是正常的rgb摄像头两个usb接口,在电脑上呈现两路摄像头通道程序检测RGB输出图像,当检测到有人脸时,用RGB人脸的位置到红 ...
- 定时任务redis锁+自定义lambda优化提取冗余代码
功能介绍: 我系统中需要跑三个定时任务,由于是多节点部署,为了防止多个节点的定时任务重复执行.所以在定时任务执行时加个锁,抢到锁的节点才能执行定时任务,没有抢到锁的节点就不执行.从而避免了定时任务重复 ...