【问题标题】:C++ where to initialize static constC++ 在哪里初始化静态常量
【发布时间】:2011-02-06 00:36:00
【问题描述】:

我有课

class foo {
public:
   foo();
   foo( int );
private:
   static const string s;
};

在源文件中初始化字符串s的最佳位置在哪里?

【问题讨论】:

    标签: c++ static initialization constants


    【解决方案1】:

    one 编译单元(通常是 .cpp 文件)中的任何地方都可以:

    foo.h

    class foo {
        static const string s; // Can never be initialized here.
        static const char* cs; // Same with C strings.
    
        static const int i = 3; // Integral types can be initialized here (*)...
        static const int j; //     ... OR in cpp.
    };
    

    foo.cpp

    #include "foo.h"
    const string foo::s = "foo string";
    const char* foo::cs = "foo C string";
    // No definition for i. (*)
    const int foo::j = 4;
    

    (*) 如果i 用于除整型常量表达式以外的代码,则必须在类定义之外定义i(如j 是)。有关详细信息,请参阅下面 David 的评论。

    【讨论】:

    • 我投了赞成票,但在查看标准后,您的代码中有一个错误:i 必须在 cpp 中定义。 §9.4.2/4 如果静态数据成员是 const 整数或 const 枚举类型,它在类定义中的声明可以指定一个常量初始化器,它应该是一个整数常量表达式 (5.19)。在这种情况下,成员可以出现在整型常量表达式中。如果在程序中使用该成员,则该成员仍应在名称空间范围内定义,并且名称空间范围定义不应包含初始值设定项。
    • 根据您对标准的引用,似乎i 必须在 用于除整数常量表达式之外的其他地方时才被定义,对吧?在这种情况下,您不能说存在错误,因为没有足够的上下文可以确定——或者严格来说,如果没有其他代码,上述示例是正确的。现在我非常感谢您的评论(+1),我自己还在学习!所以我会尝试在答案中澄清这一点,如果它更好,请告诉我......
    • @squelart 对不起,如果我听起来很愚蠢,但除了整数常量表达式之外的语句示例是什么?
    • @Saksham 例如调用函数,例如:int f() { return 42; } class foo { static const int i = f(); /* Error! */ } 注意 C++11 允许调用 'constexpr' 函数:constexpr int f() { return 42; } class foo { static const int i = f(); /* Ok */ }
    • @squelart 我阅读了文本,因此如果使用该成员,则必须提供定义 - 标准中的措辞并未将该要求限制为整数常量表达式。
    【解决方案2】:

    静态成员需要在文件范围或适当命名空间的 .cpp 翻译单元中初始化:

    const string foo::s( "my foo");
    

    【讨论】:

      【解决方案3】:

      自 C++17 起,inline 说明符也适用于变量。您现在可以在类定义中定义静态成员变量:

      #include <string>
      
      class foo {
      public:
         foo();
         foo( int );
      private:
         inline static const std::string s { "foo" };
      };
      

      【讨论】:

        【解决方案4】:

        在同一命名空间内的翻译单元中,通常在顶部:

        // foo.h
        struct foo
        {
            static const std::string s;
        };
        
        // foo.cpp
        const std::string foo::s = "thingadongdong"; // this is where it lives
        
        // bar.h
        namespace baz
        {
            struct bar
            {
                static const float f;
            };
        }
        
        // bar.cpp
        namespace baz
        {
            const float bar::f = 3.1415926535;
        }
        

        【讨论】:

          【解决方案5】:

          只有整数值(例如,static const int ARRAYSIZE)在头文件中被初始化,因为它们通常在类头中用于定义诸如数组大小之类的东西。非整数值在实现文件中初始化。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2012-08-18
            • 2015-07-11
            • 1970-01-01
            • 1970-01-01
            • 2016-10-28
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多