【问题标题】:C++ static const class members initializationC++ 静态 const 类成员初始化
【发布时间】: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)添加到您的编译器选项中。
  • 为什么你的标题是“静态常量积分成员”?这是相当误导。
  • 您希望FIRST 成为静态数据成员,因为您经常访问它?为什么限制在其他地方声明(我假设你的意思是定义)?
  • @juanchopanza:因为这是他的 C++11 之前的编译器给出的错误信息。

标签: c++


【解决方案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
    猜你喜欢
    • 1970-01-01
    • 2012-02-02
    • 2013-04-13
    • 2015-05-18
    • 2011-04-01
    • 2011-03-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多