tengo una cabecera llamada filepaths.h que define una serie de variables estáticas:¿Por qué variables estáticas necesitan ser declarados dos veces en C++
#ifndef FILEPATHS_H
#define FILEPATHS_H
class FilePaths {
public:
static QString dataFolder();
static QString profileFolder();
private:
static QString dataFolder_;
static QString profileFolder_;
};
}
#endif // FILEPATHS_H
Y un he asociado filepaths.cpp cuales al principio parecía como esto:
#include "FilePaths.h"
QString FilePaths::dataFolder() {
return dataFolder_;
}
QString FilePaths::profileFolder() {
return profileFolder_;
}
sin embargo que no funcionaron - tengo un "error de símbolo no resuelto" error de vinculador sobre todas las variables estáticas. Así que he añadido estas variables en el archivo de C++ de esta manera:
#include "FilePaths.h"
QString FilePaths::dataFolder_ = "";
QString FilePaths::profileFolder_ = "";
QString FilePaths::dataFolder() {
return dataFolder_;
}
QString FilePaths::profileFolder() {
return profileFolder_;
}
y esto funciona, sin embargo, no entiendo por qué.
¿Por qué estas variables estáticas deben definirse dos veces? ¿O tal vez no los estoy definiendo sino inicializándolos? Pero aún así, ¿por qué tiene que hacerse? ¿O debería escribir mi clase de manera diferente?
No creo que sea tan arcaico. Las declaraciones dicen que "existe en algún lugar una variable/clase/función llamada X", mientras que las definiciones dicen "X reside aquí, el compilador asigna almacenamiento para ello".La capacidad de separar declaraciones y definiciones es lo que permite múltiples unidades de traducción en un lenguaje de tipo estático sin que el compilador tenga que ser demasiado inteligente y adivinar sus intenciones. – vsekhar
No es realmente arcaico, ya que ambos estándares son (incluso ahora, C99/C++ 11) muy imprecisos en el proceso del enlazador real, y la definición en un determinado archivo cpp dará como resultado una definición en el archivo de objeto resultante, si esto no era el caso, el vinculador no encontraría una referencia única al vincular todos los códigos. – rubenvb
vsekhar, @rubenvb: Me gustaría señalar que para el código de plantilla, obtenemos múltiples definiciones (en archivos de objeto) de funciones y atributos estáticos, pero el vinculador las maneja bien. –