静态成员的多重定义?

时间:2009-08-25 06:59:57

标签: c++

无法链接以下两个文件,当我删除“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'的定义

4 个答案:

答案 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的地方,这是一个将由所有类实例共享的静态变量 - 有两行可以这样做,每个文件中有一行。删除一个将修复链接器错误。

相关问题