2011-08-17 24 views
18

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

(注意:这是为了是Stack Overflow's C++ FAQ条目如果你想批评这种形式提供帮助的想法,那么the posting on meta that started all this会做到这一点的地方回答这个问题是监测的C++ chatroom,那里的FAQ想法摆在首位开始了,所以你的答案是很可能得到那些谁的想法来到了阅读。)

+0

http://www.parashift.com/c++-faq-lite/ctors.html#faq-10.12 – PlasmaHH 2011-08-17 12:31:10

回答

26

要理解这一点,你应该有compiling and linking有很好的理解,并declarations and definitions之间的差异。


考虑下面的类:

//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

作为一个特殊的情况下,如果静态成员变量是一个常量整数或枚举类型,那么其可以具有在类定义的初始化剂:

//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关键字被施加到不在一类范围它可以采取在一个非常不同的含意的功能和对象。

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

当应用于名称空间作用域(不包括任何类或函数定义)的对象或函数时,它使用internal linkage声明对象或函数。这种用法在对象上已被弃用,因为unnamed-namespace提供了一个更好的选择。

+0

“作为一种特殊情况,如果静态成员变量是一个const整型或枚举类型,那么它可以有一个类定义中的初始化程序“。你在这里指的是class *声明吗? – 2013-08-06 16:50:50

5

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

// foo.h 

class foo { 
    static int X; 
}; 


// foo.cpp 

#include "foo.h" 

int foo::X = 0; 
相关问题