2009-08-25 27 views
7

Error al vincular los siguientes dos archivos, cuando elimino la palabra clave "estática", está bien. Probado con g ++. Verifique con readelf para el archivo de objeto, el miembro estático parece que se exporta como un símbolo de objeto global ... Creo que debería ser un objeto local ...?definición múltiple para miembro estático?

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); 
} 

Con información de error:

/tmp/ccIdHsDm.o:(.bss+0x0): múltiple definición de `StaticClass :: a '

Respuesta

16

Parece que estás tratando de tener clases locales en cada archivo fuente, con el mismo nombre. En C++ se puede encapsular clases locales en un espacio de nombres en el anonimato:

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); 
} 
+0

@Ropez: funciona bien. Gracias :) –

+0

Me siento mal con el estado de las cosas, ya que la respuesta de Ropez parece haberle dado la solución que estaba buscando. siéntase libre de mover la marca de verificación a su :) :) +1 para él, de todos modos. –

+0

@Litb, ambos tienen razón :) explicaron más. –

0

StaticClass necesita un lugar para almacenar a, una variable estática que será compartida por todas las instancias de clase; hay dos líneas que lo hacen, una en cada archivo. Al eliminar uno, se solucionará el error del enlazador.

9

La siguiente es una definición del miembro de datos estáticos. Tiene que ocurrir solo en un archivo que se compila y luego se vincula.

int StaticClass::a = 0; 

Si usted tiene múltiples tales definiciones, es como si tuviera múltiples funciones llamadas first. Chocarán y el enlazador se quejará.

Creo que está confundiendo los miembros estáticos con la estática aplicada a las variables de ámbito de espacio de nombres. En el nivel de espacio de nombres, static proporciona la vinculación interna variable o de referencia. Pero en el nivel de ámbito de clase (cuando se aplica a un miembro), se convertirá en un miembro estático, que está vinculado a la clase en lugar de a cada objeto por separado. Entonces eso ya no tiene nada que ver con el significado C de "estático".

+0

El problema es que creo que el enlazador debe saber que vincular la variable en su archivo de objeto local, ya que esta es una variable estática local, no una estática mundial uno. –

+0

no es local ni global. es un miembro de la clase. http://en.wikipedia.org/wiki/Class_variable –

+2

@arsane, si desea una clase de configuración regional, debe colocarla en un espacio de nombre anónimo.A medida que lo escribe, StaticClass de static1.cpp es la misma clase que StaticClass de static2.cpp. Antes de decir que las clases no están definidas en un encabezado, no olvide que el macroprocesador funciona por inclusión textual. – AProgrammer

2

La declaración

int StaticClass::a = 0; 

realidad asigna almacenamiento para la variable, es por ello que debe ser escrito una vez.

En cuanto a su observación, probablemente esté confundiendo dos usos diferentes de la palabra clave static. En C static, que significa "usar enlace interno", esto significa que el nombre de una variable o función no se vería fuera de la unidad de traducción donde se definió.

En las clases, static se usa para definir miembros de clase, es decir, variables o métodos que no se refieren a una instancia específica de la clase. En este caso, el almacenamiento de una variable estática debe asignarse en algún lugar (ya que no forma parte de ninguna instancia), sino solo en un lugar, por supuesto.

Cuestiones relacionadas