无法链接以下两个文件,当我删除“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);
}
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);
}
有错误信息:
/tmp/ccIdHsDm.o :(。bss + 0x0):倍数 `StaticClass :: a'的定义
答案 0 :(得分:17)
您似乎正在尝试在每个源文件中使用相同名称的本地类。在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);
}
答案 1 :(得分:9)
以下是静态数据成员的定义。它必须只在一个已编译然后链接的文件中出现。
int StaticClass::a = 0;
如果您有多个此类定义,就好像您有多个名为first
的函数。它们会发生冲突,链接器会抱怨。
我认为你错误地将静态成员静态应用于命名空间范围变量。在命名空间级别,static给出变量或引用内部链接。但是在类范围级别(当应用于成员时),它将成为静态成员 - 分别绑定到类而不是每个对象的成员。那就再与“静态”的C含义无关。
答案 2 :(得分:3)
声明
int StaticClass::a = 0;
实际上为变量分配了存储空间,这就是它应该只写一次的原因。
至于您的评论,您可能会混淆static
关键字的两种不同用法。在C static中,用于表示“使用内部链接”,这意味着在定义它的翻译单元之外不会看到变量或函数的名称。
在类中,static
用于定义类成员,即不引用类的特定实例的变量或方法。在这种情况下,静态变量的存储必须在某处分配(因为它不是任何实例的一部分),但当然只在一个地方。
答案 3 :(得分:0)
StaticClass
需要一个存储a
的地方,这是一个将由所有类实例共享的静态变量 - 有两行可以这样做,每个文件中有一行。删除一个将修复链接器错误。