如何访问类的静态const成员的地址?

时间:2013-08-07 15:09:38

标签: c++

此代码无法编译,错误信息为“未定义引用”A :: a“”:

代码1:

#include <iostream>
using namespace std;

class A
{
public:
    static const int a=0;
};

int main()
{
    cout<<&A::a<<endl;
    return 0;
}

但对于非const静态成员,它编译:

代码2:

#include <iostream>
using namespace std;

class A
{
public:
    static int a;
};
int A::a=0;

int main()
{
    cout<<&A::a<<endl;
    return 0;
}

是否无法访问类的静态const成员的地址?如果有,怎么样?为什么代码1不能编译?

3 个答案:

答案 0 :(得分:11)

const int A::a;

在源文件中,否则编译器不会为a生成地址。请注意,此处不再重复该值。

答案 1 :(得分:8)

  

此代码无法编译

代码不是链接,它确实编译。 如果要使用其地址,static const成员需要定义,因此只需添加类似于第二个代码段的定义:

const int A::a;

使用A::a表示A::a的地址为odr - 使用,以及C ++ 11标准的 9.4.2静态数据成员部分(草案n3337),第3条:

  

如果非易失性const静态数据成员是整数或枚举类型,则其在类中的声明   definition可以指定一个大括号或者相等的初始化程序,其中每个initializer子句都是赋值表达式   是一个常量表达式(5.19)。可以在。中声明文字类型的静态数据成员   使用constexpr说明符的类定义;如果是这样,其声明应指定一个支撑或等于初始化器   其中作为赋值表达式的每个initializer子句都是一个常量表达式。 [注意:两者都有   在这些情况下,成员可能出现在常量表达式中。 -end note] 仍然要定义成员   在命名空间范围内,如果在程序中使用了odr-used (3.2),则命名空间范围定义不得   包含初始化程序。

答案 2 :(得分:1)

由于你想获取地址,你仍然需要定义静态成员,就像你说的非const版本那样

int A::a;

对于const版本,您还需要

const int A::a;

请参阅here进行讨论 - 标题引用 “编译时常量没有地址。”