C++使用之常量的定义
来源:互联网 发布:开淘宝店难吗 编辑:程序博客网 时间:2024/05/18 09:27
在介绍C++的常量前,先看下下面的代码。
for (int i = 0; i < 512; ++i) {…;}
512是什么,它具有什么含义?在代码中若直接使用类似512这些“魔数”(magic number),这些数字的具体含义就不能体现出来。另外,假如程序中多处包含512这个数,随着时间的推移,发现有些512需要更改为1024,有些512需要保持不变。这种情况下,程序员必须小心谨慎地去一个一个地查找程序中所有的512,并保证更改的数字不会出错——使用“魔数”会导致难以维护的问题。
为了解决以上问题,可以使用#define预处理器指令来定义一个常量。例如,
#define MAX_NUM_SIZE 512for (i = 0; i < MAX_NUM_SIZE; ++i) {…;}
通过使用#define定义MAX_NUM_SIZE这个宏,可以清晰看到512的具体含义,另外,假如需要更改这个数字,只须直接修改#define一处就可以了。
然而,在C++中,并不提倡使用#define定义一个常量。#define本质上是一个预处理器指令,它仅仅表示使用一个串代替别一个串而已。也就是说,#define定义的常量从未被编译器看到——它们在编译器开始处理源码之前就被移走了。
具体来说,避免使用#define来定义常量,原因如下所述。
1. 没有指定类型
#define不涉及为定义的常量做类型检查,为了显式地指定常量类型,需要在常量后加上后缀。比如,对于float类型的常量,在数字后面加上f后缀。
2. 没有指定作用域
#define定义的常量是全局的。
3. 没有访问控制
不能把#define定义的常量标记为公有的,受保护的,或者私有的,它本质上是公有的。
因为宏一旦被定义,它就在其后的编译过程中有效(除非在某处被#undef)。
4. 没有符号
前面的例子中,宏MAX_NUM_SIZE可能会被预处理器从代码中剥离,这样,编译器就无法看见这个名字。这样,程序员在调试时只能看到一些没有任何描述性的常量值。
与使用#define定义常量相比,更可取的办法是使用C++的const限定修饰符来定义常量。例如,对于MAX_NUM_SIZE,可进行如下定义:
const int MAX_NUM_SIZE = 512;
作为一个整型常量,const修饰的MAX_NUM_SIZE肯定被编译器看到,当然会进入符号表。假如将MAX_NUM_SIZE定义在某个类中,还可以对其实施访问控制器和为其指定作用域。例如:
class GamePlayer{private:static const int MAX_NUM_SIZE; // static修饰符是为了确保此常量只有一份实体};const int GamePlayer:: MAX_NUM_SIZE = 512;
在上述的代码中,我们定义了一个int型的常量,该常量的作用域为GamePlayer类在,并标记为私有访问,并且会进入符号表。
值得指出的是,要注意const定义常量在某种程度上可能会使代码更臃肿。例如,在某个头文件中定义的了以下的一些常量:
const int MAX_NAME_LENGTH = 128;const float LOG_2E = log2(2.71828183f);const std::string LOG_FILE_NAME = “filename.log”;
在默认情况下,以这种方式定义的变量会促使编译器为每个包含此头文件的模块分配变量存储空间。如果定义了很多常量,并且该头文件被很多.cpp文件包含,那么会导致.o目标文件和最终的二进制文件膨胀。
解决办法是在头文件中使用extern声明常量:
// myconst.hextern const int MAX_NAME_LENGTH;extern const float LOG_2E;extern const std::string LOG_FILE_NAME;
然后在相应的.cpp文件中定义每个常量的值:
// myconst.cppconst int MAX_NAME_LENGTH = 128;const float LOG_2E = log2(2.71828183f);const std::string LOG_FILE_NAME = “filename.log”;
通过这种方式,变量的空间就只会分配一次。
使用extern来声明的常量是全局的,若要将常量的作用域限制在类中,则须在类中声明常量,并将其声明为static(这样它们就不会计入每个对象的内存大小中)。
// myclass.hclass MyClass{public:static const int MAX_NAME_LENGTH;static const float LOG_2E;static const std::string LOG_FILE_NAME;};
然后在相应的.cpp文件中定义这些常量:
// myclass.cppconst int MAX_NAME_LENGTH = 128;const float LOG_2E = log2(2.71828183f);const std::string LOG_FILE_NAME = “filename.log”;
当然,在某些情况下,使用枚举类型代替常量也可以避免文件空间膨胀的问题。
参考资料:
1. C++ Primer 中文版,第三版
2. C++ API 设计
3. Effective C++ 中文版,第三版
- C中const 定义常量的使用
- C语言使用字符串 常量的定义
- C++使用之常量的定义
- C++使用之常量的定义
- 常量的定义和使用
- swift常量的定义使用
- C语言基础之输入输出、常量定义、随机数、动态链接库的注入、数据类型介绍、goto语句的使用
- C#:定义常量的两种方法
- C/C++ 常量的定义与应用
- C语言基础之变量的命名规则、定义常量、C的数据类型
- C/C++中define定义的常量与const常量
- C语言返璞归真之修改const常量和使用变量定义数组长度
- [C++]常量定义
- C语言定义常量
- 【C++】定义常量
- PHP常量的定义以及使用
- php常量的定义和使用
- C语言之变量、常量(define\const)、变量的声明和定义
- OpenCV库文件模块
- 结构体中定义string变量
- Eclipse中设置制表符(Tab)键按下时显示为空格的样式小点点
- Java 开发 2.0: Kilim 简介
- 记录学习的点点滴滴
- C++使用之常量的定义
- LeetCode | Longest Substring Without Repeating Characters
- WebService学习之Axis2
- HDOJ 4738 - Caocao's Bridges 用tarjan找无向图的桥..注意trick
- View如何刷新?
- 基于模糊集理论的一种图像二值化算法
- HDU 4739 Zhuge Liang's Mines (2013 ACM/ICPC Asia Regional Hangzhou Online)
- 写一个函数找出一个整数数组中,第二大的数(microsoft)
- SQL Server 中的四種排序函數比较