高质量程序设计指南:C++/C语言
上QQ阅读APP看本书,新人免费读10天
设备和账号都新为新人

5.4 类中的常量

有时我们希望某些常量只在类中有效。由于 #define定义的宏常量是全局的,不能达到目的,于是可能想当然地会觉得应该用const修饰数据成员来实现。const数据成员的确是存在的,但其含义却不是我们所期望的。非静态const数据成员是属于每一个对象的成员,只在某个对象的生存期限内是常量,而对于整个类来说它是可变的,除非是static const。因为类可以创建多个对象,不同的对象其const数据成员的值可以不同。

不能在类声明中初始化非静态const数据成员。示例5-5的用法是错误的,因为在类的对象被创建之前,编译器无法知道SIZE的值是什么。

示例5-5

            class A
            {
              …
              const int SIZE=100;         // 错误,企图在类声明中初始化const数据成员
              int array[SIZE];             // 错误,未知的SIZE
            };

非静态const数据成员的初始化只能在类的构造函数的初始化列表中进行,见示例5-6。

示例5-6

            class A
            {
              …
              A(int size);                 // 构造函数
              const int SIZE ;
            };
            A::A(int size):SIZE(size)      // 构造函数的初始化列表
            {
              …
            }
            A  a(100);   // 对象a的SIZE值为100
            A  b(200);   // 对象b的SIZE值为200

那么,怎样才能建立在整个类中都恒定的常量呢?这就别指望const数据成员了,应该用类中的枚举常量来实现,见示例5-7。

示例5-7

            class A
            {
              …
              enum
              {
                  SIZE1=100,            // 枚举常量
                  SIZE2 = 200
              };
              int array1[SIZE1];
              int array2[SIZE2];
            };

枚举常量不会占用对象的存储空间,它们在编译时会被全部求值,更何况它定义的是一个匿名枚举类型。枚举常量的缺点是不能表示浮点数(如PI=3.14159)和字符串。

还可以使用另一种方法来定义类的所有对象都共享的常量,即static const,见示例5-8。

示例5-8

            class A
            {
            public:// 有些语言实现可能不支持这样的初始化,如Visual C++
              static const int SIZE1=100;    // 静态常量成员
              static const int SIZE2=200;    // 静态常量成员
            private:
              int array1[SIZE1];             // 普通成员
              int array2[SIZE2];             // 普通成员
            };