No se puede establecer el valor del campo de objeto estático (error LNK2001: símbolo externo no resuelto)

Tengo un segmento de código aparentemente simple y directo que es una versión simplificada de un problema que he tenido en un juego que estoy escribiendo. Estoy tratando de establecer un campo estático en una clase a otro valor de mi método principal. Sin embargo, este código no lo hará y no entiendo por qué.

Me sale el error

1> Source.obj: error LNK2001: símbolo externo no resuelto “public: static class A * B :: a” (? A @ B @@ 2PAVA @@ A)

class A { public: A() { } }; class B { public: static A* a; }; int main() { B::a = new A; } 

¿Cuál es la regla que dice que tengo que definir mi miembro estático de clase fuera de la clase para vincularlo?

A partir de tu comentario

pero, ¿cuál es la regla que define eso?

De la referencia c ++ dice

Definiciones y ODR

Las definiciones son declaraciones que definen completamente la entidad introducida por la statement. Cada statement es una definición, excepto por lo siguiente:

4) Declaración de un miembro de datos estáticos dentro de una definición de clase

 struct S { // defines S int n; // defines S::n static int i; // declares, but doesn't define S::i }; int S::i = 0; // defines and initializes S::i 

Como referencia adicional, también puede consultar aquí Wikipedia, Regla de una definición

ACTUALIZAR:
Finalmente encontré la última referencia estándar disponible (2 de junio de 2014) (una copia de la norma actualmente lanzada está disponible por unos 30 dólares, creo):

§ 9.4.2

2 La statement de un miembro de datos estáticos en su definición de clase no es una definición y puede ser de un tipo incompleto que no sea un vacío calificado por CV. La definición para un miembro de datos estáticos debe aparecer en un ámbito de espacio de nombres que incluya la definición de clase del miembro. En la definición en el ámbito del espacio de nombres, el nombre del miembro de datos estáticos debe ser calificado por su nombre de clase utilizando el operador ::. La expresión del inicializador en la definición de un miembro de datos estáticos está en el scope de su clase

No definiste el miembro de datos estáticos. Usted solo lo declaró en la definición de la clase. Agregue la siguiente línea

 A * B::a; 

antes de la principal.

O podrías inicializarlo con el uso de un operador nuevo.

 A * B::a = new A; 

En cuanto a tu pregunta

¿Cuál es la regla que dice que tengo que definir mi miembro estático de clase fuera de la clase para vincularlo?

luego según el párrafo n. ° 2 de la sección 9.4.2. Miembros de datos estáticos del estándar C ++.

2 La statement de un miembro de datos estáticos en su definición de clase no es una definición y puede ser de un tipo incompleto distinto de un vacío calificado por cv. La definición de un miembro de datos estáticos debe aparecer en un ámbito de espacio de nombres que incluya la definición de clase del miembro.