《Effective C++》关于const,define等总结
(将每一条item的总结和自己的理解给记录下来,以后有需要的话可以再回头参阅这些资料,不懂的再翻书温故。)
Item 02:尽量以const ,enum,inline替换#define
#define compare(x,y) func((x)>(y)?(x):(y));
//下面调用它
int a=5,b=0;
ccompare(++a,b);//a被累加两次
compare(++a,b+10);//a被累加1次
//像这种情况用define可能会出现难以捕捉的错误,而且要写很多的括号,不然可能会出现因为符号优先级的问题带来的bug
总结:
1.对于单纯的常量,尽可能用const来代替#define。
2.对于类似于函数的宏定义,可以使用inline函数来代替。
Item 03:尽可能使用const
令函数的返回值为const可以使得下面的错误避免发生
testClass a,b,c;
if(a*b=c)//如果a,b,c的operator=操作符返回值为const的,这里编译器会报错,不然找这个=号错误又要花费一段时间
关于const成员函数:
const成员函数绝对不能调用non-const成员函数,这样编译器会报错,如果要让这样的代码通过编译,要通过const_cast来将*this指针上的const属性解放。
结论:
1.将某些东西声明为const可以帮助编译器侦测出错误的用法。const可被施加于任何作用域内的对象、函数参数、函数返回类型、成员函数本体。
2.编译器强制实施bitwise constness,但你编写程序时应该使用“概念上的常量性”(conceptual constness)
3.当const和non-const成员函数有着实质的等价时候,令non-const函数调用const函数可避免代码重复(绝对不能反过来!)
Item 04:确定对象在被调用前已经被初始化了
编译单元(translation unit)是指产出单一目标文件(single object file)的那些源码。基本上它是单一源码文件加上其所含的头文件(#include files)。
st由编译单元的定义可以引出一个问题,当两个源码文件中,每一个内含至少一个non-local static 对象(也就是说该对象是global的或者位于namespace作用域内,或者class内或者file作用域内被声明为static),这时候真正的问题就产生了:如果编译器内某个non-local static对象初始化的时候依赖于另一个对象的时候,它所用到的这个对象还没有被初始化,这时候怎么办?(C++对定义于不同编译单元内的non-local static 对象的初始化顺序是没有定义的)
我们可以采用Singleton模式:将每一个对象都搬到自己的专属函数内(该对象在此函数内被声明为static),这些函数返回一个reference指向它所含的对象。然后用户调用这些函数,而不直接触及到这些对象。换句话说,non-local static函数被local static对象替换了。
这个手法的基础在于:C++保证函数内的local static对象会在“函数第一次被调用的时候初始化它”,而且这样的好处在于,程序中从来没有使用到的static对象根本就不会初始化!这会带来效率上的提升!
总结:
1.为内置类型对象进行手动初始化,因为C++不会保证初始化它们。
2.构造函数最好使用成员初值列(member initialization list),而不要在构造函数本体内使用赋值构造(可以提高效率)。初值构造的成员顺序等同于在class中这些成员的声明次序,与在list中的顺序无关(这种情况下很容易写出让人意想不到的bug,在深入探索C++模型中也有提及到这一点!)
3.为了免除“跨编译单元之初始化次序”问题,请以local static对象替换non-local static对象。
《Effective C++》关于const,define等总结的更多相关文章
- const & define & inline
0x01 const & define区别 宏定义#define发生在预编译期,而const,enum定义的常量发生在编译期,两者的重要差别在于编译期里的变量是进符号表的,而预编译期的宏是简 ...
- const define static extern
const const意味着"只读",欲阻止一个变量被改变,可以使用const关键字 const仅仅用来修饰右边的变量(基本数据变量p,指针变量*p) define #define ...
- C++ const && define
本文记录了C++中的const关键字的内容,分为3个部分,const和define的区别,const的作用,const的使用. const和define的区别 const的作用 const用于定义常量 ...
- php const define 区别有那些呢?
(1) 编译器处理方式不同 define宏是在预处理阶段展开. const常量是编译运行阶段使用. (2) 类型和安全检查不同 define宏没有类型,不做任何类型检查,仅仅是展开. const常量有 ...
- const define 定义常量的区别
1.用const定义常量在编译的时候,提供了类型安全检查,而define 只是简单地进行字符串的替换 2.const定义的常量,会分配相应的内存空间.而define没有分配空间,只是在程序中与处理的时 ...
- PHP 中 const define 的区别
在php中定义常量时,可用到const与define这两种方法,那他们到底有什么区别呢? 1.const用于类成员变量的定义,一经定义,不可修改.define不可用于类成员变量的定义,可用于全局常量. ...
- Const #define
(1) 指针本身是常量不可变 (char*) const pContent;const (char*) pContent; (2) 指针所指向的内容是常量不可变 const (char) *pCont ...
- effective c++ prefer const,enum, inline to #defines
学习心得 对于纯常量,最好以const对象或者enums替换#define #define FIRST 3 //not good enum { first=1, second=2 } ; int nu ...
- const define static extern 关键词详解
const const关键词并不能把一个变量变成一个常量, 在符号前加上const表示这个符号不能被赋值, 即他的值对这个符号来说是只读的, 但并不代表这个值不能用其他方法去改变. 通过下面的例子就能 ...
- const define区别
可以使用defined()----检测常量是否设置 [问]在php中定义常量时,const与define的区别? [答]使用const使得代码简单易读,const本身就是一个语言结构,而define是 ...
随机推荐
- jQuery $.fn.extend()方法类插件
一.为JQuery原型扩展新的属性和方法,然后在JQuery的实例对象上调用 在 jQuery 中,我们可以使用$.fn.extend()方法来定义一个方法类插件.方法类插件就是首先你使用 jQuer ...
- js函数组合
纯函数和柯里化容易引起洋葱代码 函数组合可以让我们把细粒度的函数重新组合生成一个新的函数 函数组合并没有减少洋葱代码,只是封装了洋葱代码 函数组合执行顺序从右到左 满足结合律既可以把g和h组合 还可以 ...
- JS 可编辑表格的实现
1.实现效果 用户点击语文,数学,英语部分的单元格,可以实现分数的编辑,总分也会随之变化.先看下效果,如图: 2.设计思路 先通过HTML5+CSS3绘制表格,添加input的样式和err提示动画. ...
- JUC学习笔记——共享模型之管程
JUC学习笔记--共享模型之管程 在本系列内容中我们会对JUC做一个系统的学习,本片将会介绍JUC的管程部分 我们会分为以下几部分进行介绍: 共享问题 共享问题解决方案 线程安全分析 Monitor ...
- 嵌入式-C语言基础:快速选择排序实现从大到小排序
#include<stdio.h> int main() { /*简单选择排序:从大到小:一共比较sizeArr-1轮,每一轮的第一个数是arr[i],第一个数依次和它后面的每个数比较*/ ...
- C#使用附加到进程调试
微软官网的调试进程介绍 首先运行bin下的可执行文件,然后打开源代码,选择调试--->附加到进程.
- 基于 Sealos 的镜像构建能力,快速部署自定义 k8s 集群
Sealos 是一个快速构建高可用 k8s 集群的命令行工具,该工具部署时会在第一个 k8s master 节点部署 registry 服务(sealos.hub),该域名通过 hosts 解析到第一 ...
- phpexcel 上传
<?php require_once(ROOTPATH . "inc/PHPExcel/PHPExcel.class.php");//PHPExcel//获取数据 $objP ...
- uboot引导应用程序
uboot默认是支持执行应用程序的,就像引导内核一样,我们也可以自己写一个应用程序,让uboot启动时引导. 在uboot examples/standalone 目录下,有hello_world.c ...
- Oracle12c异常关闭后启动PDBORCL(ORA-01033)
这个问题已经困扰了我好几天找解决方案,终于找到: 由于Oracle12c的特殊性,但许多用户并不想在创建用户时前面要加"C##" 那么就要创建PDBORCL数据库,来与Oracle ...