您的位置:首页 > 编程语言 > C语言/C++

C++ 各种全局常量的声明方式的优缺点

2012-09-26 16:45 274 查看
(1) 一般用途的const变量,绝对不应该声明在头文件,定义在cpp里,尤其是基础类型(int之类)这个和inline函数是类似的,编译器能自动处理不同cpp中有同样const的问题;如果不使用const变量的地址,这个const变量最终会被完全优化掉,不占静态存储空间。而如果定义成extern,会导致编译器不得不为这个变量分配一个地址,并且在使用的时候强制地去从地址取得值,这会导致极大的性能下降。比如:


const int a = 16;

inline int sqr(x)

{

return a * a;

}

myFunc(sqr(a));


在这里,编译器可以把整个sqr(a)都优化掉,替换成一个立即数256。而如果a定义成了extern,这里就必须是读数值、乘法、传参数的过程了。

C++中编译器对于const变量做了充分的优化,它完全可以取代#define常量的一切功能。

比如:


const int MAX_N = 100;

int myArray[MAX_N];


在遇到使用const变量的时候,编译器如果已知const变量的值,就会直接把值代入进行优化,和#define是完全一样的。如果最后const变量没有取地址之类的操作,编译器就会认为这个变量没有被实际引用,于是在生成代码的最后把整个const变量去掉。

const变量如果不另加定义,默认就是static的。特意去定义成extern只会破坏编译器效率。这个和C是完全不同的,所以不要把C的法则想当然地用进来。

不过对于const变量类型是复杂类型(类)的时候,static的类型可能会导致每个cpp里面都生成一个对象,这时候应该考虑extern。

(2) const变量和#define宏相比最大的好处其实不在于类型检查,而在于可以有命名空间


namespace MyNameSpace

{

#define myMacro 15

class MyClass

{

public:

    const static int myConst = 15;

#define myMacro2 16

}

const int myConst2 = 16;

}


myConst必须用MyNameSpace::MyClass::myConst来引用,myConst2对应MyNameSpace::myConst2,而#define的两个常量永远都是myMacro和myMacro2,这意味着#define的常量重名的可能性要大得多,而且很容易破坏OOP结构。

(3) 特殊情况下#define和const比可能会引起问题。比如函数重载:


void myFunc(int x)

{

...

}

void myFunc(short x)

{

...

}

const short myConst = 128;

#define myMacro 128

myFunc(myConst);

myFunc(myMacro);


#define由于没有类型,会去调用int版本的函数。这是const强制类型检查的好处

(4) const类型的编译效率比较好

因为编译器在编译的时候已经知道这个符号对应的是某类型的数了,编译会快一些。对运行影响不大。还有:


#define MAXN (12*14)

const int MAX_N = 12 * 14;


使用MAXN的时候,编译器每次都得对表达式求值;MAX_N的话,只求了一次。

(5) const类型不容易出错

这个问题是老生常谈了,#define MACRO 12+13这种写法会出问题,必须加括号。const就没这个问题。

(6) enum

enum其实可以看做是定义了一族const变量。它们同样也有命名空间,同样也有变量类型(不过变量类型是enum XXX),额外的,enum定义的常量不会使用额外的内存空间。缺点在于:enum定义的常量,类型是enum XXX,不是int。虽然可以和int型数值无限制地转换,但毕竟不是int,使用上不是那么方便,比如不能直接做加减乘除之类。

(7) #define的优势

#define在C++中的作用一般已经不是定义常量或者宏了,如前文所说这些功能应该由const和inline函数来代替。#define在C++中可以用来定义一些快捷语法,或者是根据编译选项不同生成不同内容:

#define L(x) L##x

L("abcde") // L"abcde"

#ifdef _UNICODE

#define MyFunc MyFuncW

#else

#define MyFunc MyFuncA

#endif

这些功能目前还没有其他语法可以替代。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐