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 const
enlace 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.
¿Qué quiere decir con la pregunta del ítem 5? –
@DavidHeffernan, quiero decir por qué 'x5' es una declaración pero' x4'? – Alcott