是否重新声明类外的const静态变量

时间:2014-05-03 03:22:08

标签: c++ static const declaration

在C ++ Primer 4th 12.6.2 中,建议重新声明类外的const静态变量。

但是,下面的代码在gcc 4.6.3中传递。

#include <iostream>
using namespace std;

class X {
    public:
    const static int a = 1;
};

// const int X::a;

int main() {
    X x;
    cout << x.a << endl;
    return 0;
}

我们应该重新申请吗?

PS:

根据 Potatoswatter 的建议,我添加了一个使用const静态成员作为参考的函数:

const int X::a;

void test(const int& a) {
    cout << a << endl;
}

int main() {
    X x;
    test(X::a);
    return 0;
}

如果我们在课程const int X::a之外不包含X,则会产生如下错误

undefined reference to 'X::a'

最好在类外部定义是否为const static。

3 个答案:

答案 0 :(得分:3)

不,您不需要重新声明它,因为您已经声明并在单行中定义它:

const static int a = 1;

但是,对于static数据成员(包括const static),如果您只在类中提供声明。您必须在命名空间范围内的类声明之外定义静态成员。 For example

class X
{
public:
      static int i; // declaration
};
int X::i = 0; // definition outside class declaration

答案 1 :(得分:2)

来自http://en.cppreference.com/w/cpp/language/static

  

常量静态成员

     

如果将整数或枚举类型的静态数据成员声明为const(而不是volatile),则可以使用大括号内定义的大括号括号或大小来初始化它。在这种情况下,不需要定义:

编译器的行为符合预期。没有足够的背景,很难判断“The C ++ Primer”的推荐。

答案 2 :(得分:2)

const static成员的规则有例外:

  1. 是整数或枚举类型(指针,引用,浮点数不需要应用)
  2. 永远不要使用他们的地址或绑定参考
  3. 对于static constexpr成员,类型限制被删除(或替换为constexpr的类型限制),并且必须是类内声明中的初始值设定项。

    在任何一种情况下,声明都不被认为是一个定义,尽管有一个初始化器,因此该对象在类声明(因此定义)之前不会获得地址。对于模板的成员,可以在每个翻译单元(TU)中完成,对于非模板类的成员,它必须仅在一个TU中完成。

    尽管您的示例是编译的,但实践通常不具有可伸缩性,因为此类变量无法传递给通用的传递引用函数,包括完美转发。这本书的建议很好。

    标准参考:[class.static.data]§9.4.2/ 3。