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

Fel*_*lix 1 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;
}
Run Code Online (Sandbox Code Playgroud)

但对于非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;
}
Run Code Online (Sandbox Code Playgroud)

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

Nei*_*irk 11

const int A::a;
Run Code Online (Sandbox Code Playgroud)

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

  • 对于整数,您可以将值放在头文件(/ class definition)中.这允许编译器直接使用该值来优化其他源文件中的数组大小.但它是源文件中实际分配地址的行.这是因为整个项目在内存中只有一个静态类实例,因此它只能出现在一个翻译单元中.没有它,该值实际上永远不会作为内存中的真实对象存在.该值只是被编译器"复制并粘贴",然后被调用然后被遗忘. (3认同)

hmj*_*mjd 8

这段代码无法编译

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

const int A::a;
Run Code Online (Sandbox Code Playgroud)

A::a平均值的地址A::a有用的,并且从第9.4.2节C++ 11标准的静态数据成员(草案n3337),第3节:

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