对静态成员有一个未定义的引用意味着什么?

我刚刚用一些静态数据成员编写了一个类,但现在我得到关于“未定义引用”的错误。 为什么这不起作用? 我究竟做错了什么?

(注意:这是一个Stack Overflow的C ++常见问题解答的入口,如果你想批评在这个表单中提供常见问题的想法,那么开始所有这些的meta上的贴子将成为这样做的地方。那个问题在C ++聊天室中进行监控,常见问题的想法首先出现在C ++聊天室中,所以你的答案很可能会被那些提出这个想法的人阅读。)


要理解这一点,您应该对编译和链接以及声明和定义之间的差异有很好的理解。


考虑以下课程:

//In header file
class Example {
    static bool exampleStaticMember;
};

这里, exampleStaticMember被声明但没有被定义。 这意味着如果exampleStaticMember的使用方式意味着它必须有一个地址,那么它必须有一个单独的定义。 通常,在类定义中不声明静态数据成员是该成员的定义。

所需的声明通常放在包含该类成员的其他定义的cpp文件中。 它必须与类定义在同一个命名空间中。 定义通常如下所示:

//In source file:
//This may optionally have an initialiser (eg "= true")
bool Example::exampleStaticMember; 

该定义可以放在任何cpp文件中,但不应将其放在包含该类的头文件中,因为这可能会破坏One Definition Rule。

作为一种特殊情况,如果静态成员变量是一个const整型或枚举类型,那么它可以在类定义中具有一个初始化器:

//In header file
class Example {
    static const int initialised = 15;
};

在这种情况下,cpp文件中的定义仍然是必需的,但不允许有一个初始化程序:

//In source file
//Note: no initialiser!
const int Example::initialised;

已经被初始化的静态成员可以在常量表达式中使用。

模板

对于模板的静态数据成员,情况稍有不同。 静态成员应该在头部以及类的其他部分中定义:

//In header file
template<typename T>
class Example {
    static int exampleInt;
    static T exampleT;
}
template<typename T> int Example<T>::exampleInt;
template<typename T> T Example<T>::exampleT;

这是有效的,因为对类模板的静态数据成员有一个定义规则的特定例外。

静态的其他用途

static关键字应用于不在类作用域中的函数和对象时,它可以具有非常不同的含义。

当应用于函数作用域中的对象时,它将声明一个对象,该对象在函数的第一次执行中被初始化,并随后在函数调用之间保持其值。

当应用于名称空间作用域(不包括任何类或函数定义)的对象或函数时,它会使用内部链接声明对象或函数。 由于未命名空间提供了更好的替代方法,因此对于对象不推荐使用此用法。


您必须实例化.cpp文件中标头中定义的静态成员。 例如:

// foo.h

class foo {
    static int X;
};


// foo.cpp

#include "foo.h"

int foo::X = 0;
链接地址: http://www.djcxy.com/p/12691.html

上一篇: What does it mean to have an undefined reference to a static member?

下一篇: Object destruction in C++