无法链接以下两个文件,当我删除"static"关键字时,则没关系.用g ++测试.用readelf检查对象文件,静态成员似乎被导出为全局对象符号......我认为它应该是一个本地对象......?
static1.cpp
class StaticClass
{
public:
void setMemberA(int m) { a = m; }
int getMemberA() const { return a; }
private:
static int a;
};
int StaticClass::a = 0;
void first()
{
StaticClass statc1;
static1.setMemberA(2);
}
Run Code Online (Sandbox Code Playgroud)
static2.cpp
class StaticClass
{
public:
void setMemberA(int m) { a = m; }
int getMemberA() const { return a; }
private:
static int a;
};
int StaticClass::a = 0;
void second()
{
StaticClass statc1;
static1.setMemberA(2);
}
Run Code Online (Sandbox Code Playgroud)
有错误信息:
/tmp/ccIdHsDm.o:(.bss+0x0):`StaticClass :: a'的多重定义
Rop*_*pez 18
看起来你正试图在每个源文件中使用相同名称的本地类.在C++中,您可以将本地类封装在匿名命名空间中:
namespace {
class StaticClass
{
public:
void setMemberA(int m) { a = m; }
int getMemberA() const { return a; }
private:
static int a;
};
int StaticClass::a = 0;
} // close namespace
void first()
{
StaticClass statc1;
static1.setMemberA(2);
}
Run Code Online (Sandbox Code Playgroud)
以下是静态数据成员的定义.它必须只在一个已编译然后链接的文件中出现.
int StaticClass::a = 0;
Run Code Online (Sandbox Code Playgroud)
如果您有多个这样的定义,就好像您调用了多个函数一样first.它们会发生冲突,链接器会抱怨.
我认为你错误的静态成员静态应用于命名空间范围变量.在命名空间级别,static给出变量或引用内部链接.但是在类范围级别(当应用于成员时),它将成为静态成员 - 分别绑定到类而不是每个对象的成员.那就再与"静态"的C含义无关.
该声明
int StaticClass::a = 0;
Run Code Online (Sandbox Code Playgroud)
实际上为变量分配存储空间,这就是为什么它应该只被写入一次。
至于您的评论,您可能会混淆该static关键字的两种不同用法。在 C 中,static 用来表示“使用内部链接”,这意味着变量或函数的名称在定义它的翻译单元之外不会被看到。
在类中,static用于定义类成员,即不引用类的特定实例的变量或方法。在这种情况下,静态变量的存储必须分配在某处(因为它不是任何实例的一部分),但当然只能分配在一个地方。