【问题标题】:definition of static const outside the class definition在类定义之外定义静态常量
【发布时间】:2011-05-24 05:45:21
【问题描述】:

我们是否应该在类定义之外定义一个static const 成员,即使它是在类内部初始化的?

#include<iostream>  
using namespace std;  
class abc  
{  
    static const int period=5;  
    int arr[period];  
  public:  
    void display()   
    {   
        cout<<period<<endl;  
    }  
};

const int abc::period;   

int main()   
{   
    abc a;  
    a.display();   
    return 0;  
}

在评论// const int abc::period; 后,这两个版本的代码在 gcc 4.3.4 上运行良好。所以我想问一下为什么这两个版本都可以工作,哪个版本符合标准?

【问题讨论】:

    标签: c++ c++11


    【解决方案1】:

    你正在定义静态成员period,写成const int abc::period;。您可以为类的static const 成员提供类内初始化程序,但这不是定义,而仅仅是声明。

    9.4.2/4 - 如果静态数据成员是 const 整数或 const 枚举类型,它在类定义中的声明可以指定一个常量初始化器,它应该是一个整数常量表达式 (5.19)。在这种情况下,成员可以出现在整型常量表达式中。如果在程序中使用该成员,则该成员仍应在命名空间范围内定义,并且命名空间范围定义不应包含初始值设定项。

    即使没有定义,您的代码也会编译,因为您没有获取静态成员的地址。 Bjarne Stroustrup 在 C++-FAQ here 中提到 当(且仅当)静态成员具有类外定义时,您可以获取静态成员的地址

    【讨论】:

    • @David :我试图在标准中搜索 use 这个词。很遗憾,在发这篇文章时找不到相关的文字。
    • :) 我前段时间也尝试过,但在 C++03 中没有找到任何可以发布的明确定义,但 用作左值,其中左值到右值的转换没有立即执行 是一个稍微好一点的近似值。对于此定义适用且获取地址不适用的情况:(cond?static_const:XXX)cond 是一个条件,static_const 是一个类中的静态常量。如果XXX 是右值,则不构成使用。 static_const 是一个右值,但立即转换为左值。如果XXX 是左值,则构成使用。没有地址。
    • 例子:struct test { static const int s = 1; }; int main( int argc, char** ) { const int y = ( argc &lt; test::s? argc : test::s); }第一次使用test::s不构成使用argc &lt; test::s,该常量是左值,而是立即转换为右值(它是值),执行。另一方面,...: test::s ) 确实构成使用。三元表达式可以理解为(伪代码):const int* __p; if ( argc&lt;test::s ) __p = &amp;argc; else __p = &amp;test::s; *__p;
    • 如果将表达式更改为( argc &lt; test::s? argc : test+0 ),那么在两个子表达式中,都会立即转换为右值,它们不构成使用。等效的伪代码为:int __i; if ( argc &lt; test::s ) __i = argc; else __i = test+0; __i;
    • @David:总结得很好! :-)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-17
    • 1970-01-01
    • 2020-01-10
    • 2013-04-11
    相关资源
    最近更新 更多