C++类中常量定义

来源:互联网 发布:美图秀秀软件怎样赚钱 编辑:程序博客网 时间:2024/06/09 19:40

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

 

    (1)不能在类声明中初始化const数据成员。

以下用法是错误的,因为类的对象未被创建时,编译器不知道SIZE的值是什么。

    class A

    {…

        const int SIZE = 100;     // 错误,企图在类声明中初始化const数据成员

        int array[SIZE];        // 错误,未知的SIZE

    };

 

 

(2)const数据成员的初始化只能在类构造函数的初始化表中进行

例如

    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

 

 

    (3)怎样才能建立在整个类中都恒定的常量呢?别指望const数据成员了,应该用类中的枚举常量来实现。

       例如

    class A

    {…

        enum { SIZE1 = 100, SIZE2 = 200}; // 枚举常量

        int array1[SIZE1];

        int array2[SIZE2];

    };

    枚举常量不会占用对象的存储空间,它们在编译时被全部求值。枚举常量的缺点是:它的隐含数据类型是整数,其最大值有限,且不能表示浮点数(如PI=3.14159)。

//------------------------------------------------------------------------

如果你想得到一个可用于常量表达式中的常量,例如数组大小的定义,那么你有两种选择:

 class X {  static const int c1 = 7;  enum { c2 = 19 };  char v1[c1];  char v2[c2];  // ... };
一眼望去,c1的定义似乎更加直截了当,但别忘了只有static const的整型或枚举型量才能如此初始化。
这就很有局限性,例如
 class Y {  const int c3 = 7;  // error: not static  static int c4 = 7;  // error: not const  static const float c5 = 7; // error not integral };
(在自己的VC++6.0运行static const int c1 = 7;是报错的,估计是编译器太老了)
我还是更喜欢玩“enum戏法”,因为这种定义可移植性好,而且不会引诱我去使用非标准的“类内初始化”扩展语法。

那么,为何要有这些不方便的限制?因为类通常声明在头文件中,而头文件往往被许多单元所包含。但是,为了避免链接器设计的复杂化,C++要求每个对象都只能被定义一次。如果C++允许类内定义要作为对象被存在内存中的实体,那么这项要求 就无法满足了。

关于C++设计时的一些折衷,参见《The Design and Evolution of C++》。

如果这个常量不需要被用于常量表达式,那么你的选择余地就比较大了:

 class Z {  static char* p;  // initialize in definition  const int i;  // initialize in constructor public:  Z(int ii) :i(ii) { } }; char* Z::p = "hello, there";
只有当static成员在类外被定义了,你才可以获取它的地址,例如:
 class AE {  // ... public:  static const int c6 = 7;  static const int c7 = 31; }; const int AE::c7; // definition int f() {  const int* p1 = &AE::c6; // error: c6 not an lvalue  const int* p2 = &AE::c7; // ok  // ... }

0 0
原创粉丝点击