C++ 静态 const 类成员初始化

Posted

技术标签:

【中文标题】C++ 静态 const 类成员初始化【英文标题】:C++ static const class members initialization 【发布时间】:2014-05-20 18:23:52 【问题描述】:

我想拥有一个自身具有 static 成员的类,但我不知道该怎么做。这可能吗?

我得到错误:

只有静态常量整数数据成员可以在类中初始化

代码:

namespace misc

    class CData
    
    public:
        CData( )  ;
        CData( int d );

        CData& operator = ( const CData& d );

        static const CData FIRST = CData( 512 ); //how?

    private:
        int data;
    ;

由于我经常使用FIRST,我想使用misc::CData::FIRST 静态访问它,而无需在范围内的某处声明它。这有可能吗?

【问题讨论】:

您正在使用旧的编译器,或者它处于旧模式。尝试将--std=c++11(或--std=gnu++11)添加到您的编译器选项中。 ***.com/questions/6106194/… 为什么你的标题是“静态常量积分成员”?这是相当误导。 您希望FIRST 成为静态数据成员,因为您经常访问它?为什么限制在其他地方声明(我假设你的意思是定义)? @juanchopanza:因为这是他的 C++11 之前的编译器给出的错误信息。 【参考方案1】:

... 无需在范围内的某处声明它。这有可能吗?

不,如果不声明它是不可能的(您已经在类声明中尝试过这样做)。您可能的意思是,没有在您的类声明之外定义它。答案再次是否定的。 对于这种情况,您必须将声明和定义分开(它仅适用于像 int 这样的原始整数类型,以便直接在类声明中初始化它们)。

首先在你的类声明中有一个简单的声明(通常类似于CData.hpp

namespace misc 
    class CData 
    public:
        CData( )  ;
        CData( int d );

        CData& operator = ( const CData& d );

        static const CData& FIRST;

    private:
        int data;
    ;

然后在单独的编译单元中定义它(通常类似于CData.cpp

namespace misc 
    const CData& CData::FIRST = CData( 512 );

【讨论】:

"...无需在范围内的某处清除它..." @privatedatapublicchannel2 "...无需在范围内的某处清除它..."这与要求仙女或独角兽无关... 无关是假设,但“不需要在范围内的某个地方清除它”是 OP 的愿望,它是问题的一部分 @privatedatapublicchannel2 那么OP应该澄清这一点,你不这么认为吗?经常有人希望从 c++ 中获得这个或那个,而该语言根本不支持。 我的意思是“全球范围”。我发现将它放在“Data::FIRST”类中更好,这样你就知道它属于什么,而不是“extern DATA bla..”,如果你有很多数据,我认为这有点混乱。感谢您的帖子,这很完美+1【参考方案2】:

对于非整数数据,这样的东西是首选,因为它避免了static initialization fiasco.

static const CData FIRST()

    static CData first(512); //only initialized once, when first requested

    return first;

【讨论】:

【参考方案3】:

... 无需在范围内的某处声明它。是不是由 有机会吗?

没有。

C++ 标准 n3337 § 9.4.2/2

静态数据成员

静态数据成员在其类定义中的声明不是 定义,并且可能是除 cv 限定之外的不完整类型 空白。静态数据成员的定义应出现在 包含成员的类定义的命名空间范围。 (...)

你可以在类中声明一个静态数据成员:

namespace misc 
    class CData 
    public:
        //...
        static const CData FIRST;  // declaration
        //...

并在(完全)其中一个 .cpp 文件中定义它:

namespace misc 
    CData CData::FIRST = CData( 512 );  // definition

这是首选解决方案,但是您需要将此定义排除在您的班级之外。如果它是一个整数类型,你可以在类中定义成员

C++ 标准 n3337 § 9.4.2/3 说

如果非易失性 const 静态数据成员是整数或 枚举类型,其在类定义中的声明可以指定 一个大括号或相等初始化器,其中每个初始化器子句是 赋值表达式是一个常量表达式 (...)

【讨论】:

我没有投反对票,但我认为这个问题与这里的单例模式并不真正相关:-/ ... 那么解决OP问题最直接的方法就是创建一个单例? 好吧,OP 似乎也认为他需要静态数据成员,因为他经常访问它。原始问题的答案是为静态成员提供定义,而不是创建单例。无论如何,没有投反对票,所以无法帮助您。 @πάνταῥεῖ 现在它确实提供了更多信息 @privatedatapublicchannel2 you've come a long way baby

以上是关于C++ 静态 const 类成员初始化的主要内容,如果未能解决你的问题,请参考以下文章

C++类和对象下

C++ staticconst和static const 以及它们的初始化

class中static总结-静态成员函数和静态成员变量

将 const char[] 初始化为非静态类成员

C++ const修饰类成员的说明

静态成员变量初始化 C++