Effective C++之旅 之 const, enmu, inline and #define
来源:互联网 发布:耐克在淘宝有旗舰店吗 编辑:程序博客网 时间:2024/05/22 11:30
在开始之前,先简述一下C++语言。以前一直不知道该怎么定义C++语言,因为用C++写个面向过程的程序也一样可以。现在做一个分析,C++语言是一个多重规则的语言,可以理解为一个由多种语言组合在一起的集合。就好比一个瑞士军刀,里面有好多针对不同功能的工具。
C++基本由四种语言组成:c,OOC++,Template C++和STL。
C就是我们所说的纯C语言,没有模板,没有重载,没有异常;
OOC++就是典型的面向对象编程,所以包括三个基本特征:encapsulation, inheritance and polymorphism。
template C++即泛型编程,威力强大。
STL,它是一个template程序库,功能强大。
不同的语言,有不同的规则,选择对应语言,遵循对应的规则,就能编出高效的程序,比如C语言的内置类型int,pass by value的效率高于pass by reference,而OOC++和template C++的对象,由于构造函数和析构函数的存在,pass by reference比pass by value要高效。同理,STL,它的iterator和函数对象都是基于C指针塑造出来的,所以pass by value更高效,你在STL里找不到reference的应用。
关于C++的分析就这么多,下面继续标题上的point
POINT 3,尽可能的用const, enum替换#define定义的字串或数值常量
首先说用#define定义常量字串,数值存在的问题,比如#deine PI 3.1415926
1. 编译器不知道PI的存在,因为它已经被预处理器改为3.1415926,所以不会将PI加入到symbol table中,编译的时候,我们根本不能靠PI来搜索到它,出问题时很难定位。
2. 没有类型的概念,做数值可以,做字串用也可能,编译器发现不了类型不匹配的错误。
3. 没有常量scope的概念,所以很容易成为一个全局的变量。没有封装变量而言。
下面要说的const就能解决所有上面的问题了,所以用const替代#define定义的字串,数值常量是完全可以的。
const的使用,可能大家也都知道,这个以后会详细说。这里只说一下用const实现的scope变量的限制。以一个class的定义为例:
class A
{
static const int numbers = 5; //这种叫in class 初值设定
int scope[numbers];
...;
}
这里你看到的numbers是声明,而不是定义,通常C++要求我们必须提供定义后才能使用,但是对于statc且为整数类型的变量(int, char, bool等),只要不取它们的地址,我们就可以无需定义直接使用,所以上面的scope数组的numbers可以直接使用。
但是如果编译器不支持这种的话,那我们就不得不写出定义式了,其实也很简单,只是在class 定义外面做如下定义:
const int A::numbers; //这里无需赋值,因为numbers在声明时已获得初值,所以这里不用再赋值。
如果编译器不支持声明in class初值设定,那拿到外面赋值也是一样的,const int A::numbers = 5; 但是这样的话,scope数组里的numbers就不能使用了, int scope[numbers]; 就不能这样定义了,所以这里有另外一种所谓的enum hack的方法,如下:
class A
{
emum {numbers = 5};
int scope[numbers]; //这就没有问题了
...
}
显然,这里的enum起到了一个#define的作用,但是它是由scope限定的,比define更具有安全性和私密性。
这里需要提到一点,通常const 定义的变量,我们是可以访问该变量的地址的,但是enmu和define的定义的变量,我们是访问不了地址的。
总结:常量定义的优先顺序为:const > enum > define,原则就是:能让编译器处理的就不要用预编译器帮忙。
POINT4, 用inline替代#define定义的宏函数
对于另外一种常见的#define使用的方式就是定义宏,如下:
#define MAX_VALUE(a, b) fun( (a) > (b) ? (a) : (b) )
这是个典型的函数宏,这样做的好处是,它可以直接把后面的语句替换到code中,而不会导致function call带来的而外开销,如果你这么做当然就会有这个开销:
void MAX_VALUE(a, b) { func(a > b ? a : b); } //这里有个调用的开销
用define来实现这样的宏有如下的风险:
1. 实参的封闭性,a 必须用小括号包起来,原因大家应该都知道,因为a可能是个表达式。
2. 逻辑混乱,可能出现以下的问题:
int a = 5, b =0;
MAX_VALUE(++a, b); //这里,a会被加两次,最后 a = 7被传给fun
MAX_VALUE(++a, b+10); //这里a被加一次,最后b = 10被传给fun
a被加几次竟然取决于b,逻辑很乱。所以这里我们提出用inline来代替#define,完全可以摆脱这种问题,如下:
template <typename T>
inline void max_value(const T& a, const T& b) { fun( a > b ? a : b); }
同时,因为定义为内联函数,所以编译器当然会把解析过的code直接替换max_value,同样也没有function call的开销,何乐而不为呢?
本节总结:
对于单纯的变量,int,char,string等,尽量用const,enum替代#define
对于函数宏,用inline替代#define
待续... ...
- Effective C++之旅 之 const, enmu, inline and #define
- Effective C++(Item1) Prefer const and inline to #define
- 《Effective C++》尽量以const,enum,inline,替换#define
- effective C++:尽量以const、enum、inline替换#define
- 《Effective C++》:尽量用const和inline取代#define(1)
- Effective C++学记之02 使用const enums inline来代替#define
- Effective C++读书笔记之二:尽量以const,enum,inline替换#define
- 在c++中尽量使用const,enmu,inline来代替#define
- EffictiveC++笔记之用const、enum、inline替换define
- C++学习之inline、#define、const和static的解释
- 尽量用const和inline而不用#define(摘自effective C++)
- 重读经典-《Effective C++》Item2:尽量以const,enum,inline替换#define
- 重读经典-《Effective C++》Item2:尽量以const,enum,inline替换#define
- 《Effective C++》条款02:尽量以const,enum,inline替换#define
- 重读经典-《Effective C++》Item2:尽量以const,enum,inline替换#define
- Effective C++(一)尽量使用const和inline来替代#define
- Effective C++:条款1:尽量用const和inline而不用#define
- 重读经典-《Effective C++》Item2:尽量以const,enum,inline替换#define
- Open flash chart 2 work on GAE
- 关于/etc/bashrc和$HOME/.bashrc
- 更好的网站 - 你知道网站被屏蔽了吗?
- linux: 编译android源代码流程,以及linux环境变量设置。
- JAVA 连接ORACLE10g实例与可能出现问题(传统方式连接)
- Effective C++之旅 之 const, enmu, inline and #define
- 转 mschart 自定义属性
- DLL注入程序的一般步骤
- 一石三鸟的总结策略
- ftp上传 下载文件
- javascript实现层上下移动
- Cassandra分布式Hash表系统测试报告
- 常用正则表达式
- 不需搜索,只要推荐 第二代网购模式探讨