所以,假设我有一个这样的标题:
#ifndef BASECLASS_H
#define BASECLASS_H
class BaseClass
{
public:
static int getX(){return x;}
private:
static int x;
};
int BaseClass::x = 10;
#endif
Run Code Online (Sandbox Code Playgroud)
我多次听说过我不应该在头文件中初始化静态变量,而是在cpp中.但是因为有守卫,所以应该只有一个BaseClass :: x副本.所以我有点不明白为什么要放
int BaseClass::x = 10;
Run Code Online (Sandbox Code Playgroud)
在cpp.谢谢.
Nat*_*one 10
如果在标题中执行此操作,则只要从多个CPP文件中包含多个定义错误,就会出现多个定义错误.在声明时,你真的告诉编译器两件事
int BaseClass::x = 10;
Run Code Online (Sandbox Code Playgroud)
首先,您要定义符号BaseClass :: x; 第二,你告诉它你希望它的初始值为10.根据一个定义规则,这只能在你的程序中发生一次.
如果您考虑预处理器实际执行的操作,可能会更容易理解:它将所有包含的头文件的内容复制到cpp文件中并将其传递给编译器.
现在让我们说你有:
// In a.cpp
#include <baseclass.h>
// more code
// In b.cpp
#include <baseclass.h>
// more code
Run Code Online (Sandbox Code Playgroud)
预处理器扩展包含后,两个文件将包含:
int BaseClass::x = 10;
Run Code Online (Sandbox Code Playgroud)
现在,只要两个目标文件都传递给链接器,它就会看到符号BaseClass::x两次 - 这是一个错误.
现在,为了使它更加明显,想象一下你会把它放在一个头文件中:
int aGlobalVariable = 10;
Run Code Online (Sandbox Code Playgroud)
然后将它包含在两个不同的cpp文件中,这两个文件都应链接到一个可执行文件中.如果从链接器的角度来看,它实际上与您的示例没有任何不同.
为什么这不是类声明的问题?
声明和定义之间存在差异.只有后者会引起问题.例如,以下所有都是声明:
extern int a;void foo(int a);class Foo { int bar(); };而这些是定义:
int a;int b = 10;void foo(int a) { /*..*/ }int Foo::bar() { /*...*/ }只要有一个(并且只有一个)定义,您可以拥有任意数量的声明,并且链接器将确保它们都引用相同的函数或内存位置.
那课怎么样?只能声明类,而必须定义它们的成员函数和静态成员.同样,每个定义可能只存在一次.
成员函数和静态成员实际上只在程序的地址空间中存在一次,而对于类的每个对象都存在普通成员(实例变量).
回到你的具体问题:静态成员基本上只是全局变量,但是作用于类的名称.
希望这能为您解决问题!