美文网首页C++
[C++] class专属常量

[C++] class专属常量

作者: 何幻 | 来源:发表于2017-05-03 10:28 被阅读143次

    为了将常量的作用域限制于class内,你必须让它成为class的一个成员,
    而为确保此常量至多只有一份实体,你必须让它成为一个static成员。

    class GamePlayer{
    private:
    
        // 常量声明式
        static const int NumTurns = 5;
    
        // 使用该常量
        int scores[NumTurns];
    };
    

    然而,NumTurns是常量的声明式而非定义式,通常C++要求你对你所使用的任何东西提供一个定义式。
    但如果它是一个class专属常量又是static,且为整数类型(integral type,例如int,char,bool),则需特殊处理。
    只要不取它们的地址,你可以声明并使用它们而无须提供定义式。

    但如果你取某个class专属常量的地址,或纵使你不取其地址但是编译器却(不正确的)坚持要看到一个定义式,
    你就必须另外提供定义式如下:

    // NumTurns的定义
    const int GamePlayer::NumbTurns;
    

    请把这个式子放进一个实现文件,而不是头文件中。
    由于class常量已在声明时获得初值,因此定义时不可以再设初值。

    旧式编译器也许不支持上述语法,它们不允许static成员在其声明式上获得初值。
    此外,所谓的“in-class初值设定”也只允许对整数常量进行。
    如果你的编译器不支持上述语法,你可以将初值放在定义式:

    class CostEstimate{
    private:
        // static class常量声明,位于头文件
        static const double FudgeFactor;
    
        ...
    };
    
    // static class常量定义,位于实现文件中
    const double CostEstimate::FudgeFactor = 1.35;
    

    这几乎是你在任何时候唯一需要做的事,唯一例外的是在class编译期间需要一个class常量值,
    例如,在上述的GamePlayer::scores的数组声明式中,
    是的,编译器坚持必须在编译期间知道数组的大小。

    这时候,万一你的编译器(错误的)不允许“static整数型class常量”完成“in-class初值设定”,
    可改用所谓的“the enum hack”补偿做法。
    其理论基础是:“一个属于枚举类型的数值可权充int被使用”。

    于是GamePlayer可定义如下:

    class GamePlayer{
    private:
        // “the enum hack”,令NumTurns成为5的一个记号名称
        enum { NumTurns = 5 };
    
        // 这就没问题了
        int scores[NumTurns];
    
        ...
    };
    

    “enum hack”的行为某方面说比较像#define,而不像const
    例如,取一个const的地址是合法的,但取一个enum的地址就不合法,而取一个#define的地址通常也不合法。
    如果你不想让别人获得一个pointer或reference指向你的某个整数常量,enum可以帮助你实现这个约束。
    此外,虽然优秀的编译器不会为“整数型const对象”设定另外的存储空间
    (除非你创建一个pointer或reference指向该对象),不够优秀的编译器却可能如此,而这可能是你不想要的。
    enum#define一样绝不会导致非必要的内存分配。


    Effective C++ - P14

    相关文章

      网友评论

        本文标题:[C++] class专属常量

        本文链接:https://www.haomeiwen.com/subject/vgdktxtx.html