2012-03-28 10 views
7
//a.h 

extern int x1; 
static int x2; 
int x3; 
static const int x4; 

class A { 
    public: 
     static const int x5 = 10; 
}; 

a.h será incluido por múltiples archivos .cpp, mi pregunta es:`static`,` extern`, `const` en el archivo de cabecera

1. x1 es sólo una declaración, ¿no es así? Entonces su definición debe hacerse en uno de esos archivos .cpp, ¿verdad?

2. x2 es una definición, ¿verdad? Yo solía pensar que static int también es una declaración como extern int, pero estaba equivocado. x2 solo será visible en a.h?

3. se definirán varias veces si a.h está incluido en múltiples .cpp archivos, por lo que se traducirá en de compilación de error, ¿verdad?

4. x4 es una definición, ¿verdad?

5. Aquí en la clase A, x5 es una declaración, sí. Pero ¿qué pasa con x4?

+0

¿Qué quiere decir con la pregunta del ítem 5? –

+0

@DavidHeffernan, quiero decir por qué 'x5' es una declaración pero' x4'? – Alcott

Respuesta

10

1.x1 es sólo una declaración, ¿no es así? Entonces, su definición debería hacerse en uno de esos archivos .cpp, ¿verdad?

correcta

2.x2 es una definición, ¿verdad? Solía ​​pensar que static int también es una declaración como extern int, pero estaba equivocado. x2 solo será visible en a.h?

Un x2 diferente estará disponible en cada unidad de traducción que incluya el encabezado.

3.x3 se definirá varias veces si a.h se incluye en varios archivos .cpp, por lo que x3 dará como resultado error de compilación, ¿no?

Más precisamente, dará como resultado un error de enlazador. El compilador procesa cada unidad de traducción, el enlazador las une y detecta que el símbolo se define varias veces.

4.x4 es una definición, ¿verdad?

Sí, es una definición, pero como con x2 cada unidad de traducción tendrá su propia x4 (tanto por static y porque es lo que implica constenlace interno

5.Here en la clase A, x5 es una declaración, sí. Pero ¿qué ocurre con x4?

Sí, x5 es una declaración solamente (con inicialización). Puede surgir porque la palabra clave static se reutiliza para significar cosas diferentes en contextos diferentes. En x5 que significa atributo de la clase, mientras que en x4 que significa enlace interno

Este último caso es especial. Es la única declaración (IIRC) donde la declaración puede tener un valor, y la razón es que permite al compilador usar el valor de la constante en todas las unidades de traducción que incluyen ese encabezado como compilar constante de tiempo. Si el valor debe proporcionarse con la definición, solo una unidad de traducción tendrá acceso a ese valor. La definición de este miembro estático sería:

const int A::x5; // no initialization here 

Y usted debe proporcionar uno si el miembro es ODR-usa. Ahora bien, en la mayoría de los casos, la constante no será odr-used, ya que el compilador sustituirá el valor cuando se utilice la expresión A::x5. Sólo cuando el miembro se utiliza como un lvalue que necesita la definición, por ejemplo:

void f(const int &) {} 
int main() { 
    f(A::x5); 
} 

Debido a que el argumento para f es una referencia, el uso de A::x5 requiere una lvalue (nota, const-dad y lvalue/rvalue-ness son casi ortogonales), y eso requiere la definición del miembro en una sola unidad de traducción en su programa.

+0

¿Qué es 'vinculación interna'? – Alcott

+0

@Alcott: no se puede acceder al símbolo desde fuera de la unidad de traducción en la que está definido. Esto implica que si múltiples unidades de traducción definen un símbolo con el mismo nombre con enlace interno, cada unidad de traducción obtendrá su propio símbolo diferente (es decir, símbolos diferentes incluso si tienen el mismo nombre). –

4
  1. correcta

  2. Es una definición, x2 será 0, y cada unidad de traducción que contiene el encabezado tendrá su propia copia de x2.

  3. Sí, pero dará como resultado un error de enlazador, no un compilador.

  4. Igual que 2., pero no puede modificarlo.

  5. Dentro de una clase, static tiene un significado diferente. Es legal allí simplemente porque x5 es de tipo integral const, que también se inicializa.

+0

Entonces 'x2' no es una var global que se puede compartir entre múltiples archivos' .cpp'? – Alcott

+0

@LuchianGrigore: en una sola unidad de traducción, la define como 'const int A :: x5;' (no se permite inicialización en la definición). Si desea verificar que esto no sea una definición, agregue al programa: 'void f (const int &) {} int main() {f (A :: x5); } 'y obtendrá un error de enlazador (hasta que agregue la definición). –

+0

@Alcott no, x2 será diferente para cada archivo 'cpp'. –

Cuestiones relacionadas