2011-05-26 14 views
16

Antes de que alguien me llame por no mirar las preguntas preexistentes, he visto y me doy cuenta de que tiene que ver con la declaración, pero todavía no puede hacer que funcione (podría ser algo que tenga que ver conmigo usando vectores).C++ vector issue - 'LNK2001: símbolo externo no resuelto private: estático ...'

Manager.h:

#include "Flight.h" 
#ifndef manager_h 
#define manager_h 

class Manager { 
    static vector<Airport> airports; 
    static vector<Flight> flights; 
public: 
    static void loadAirports(); 
    static void loadFlights(); 
    static Airport getAirport(string code); 
    static vector<string> split(const string &s, vector<string> &elems); 
}; 

#endif 

Manager.cpp:

#include "Manager.h" 

void Manager::loadAirports() 
{ 
    ifstream airportfile("airports.txt"); 
    string line; 
    while (getline(airportfile, line)) 
    { 
     vector<string> values; 
     split(line, values); 
     Airport airport (values[0], values[1], atoi(values[2].c_str())); 
     airports.push_back(airport); 
    } 
} 

void Manager::loadFlights() 
{ 
    ifstream flightfile("flights.txt"); 
    string line; 
    while (getline(flightfile, line)) 
    { 
     vector<string> values; 
     split(line, values); 
     Flight flight (getAirport(values[0]), getAirport(values[1]), atoi(values[2].c_str()), atoi(values[3].c_str())); 
     flights.push_back(flight); 
    } 
    cout << flights.size() << endl; 
} 

Airport Manager::getAirport (string code) 
{ 
    for (int i = 1; i < (int)airports.size(); i++) 
    { 
     if (airports[i].code == code) 
      return airports[i]; 
    } 
    throw exception(); 
} 

vector<string> Manager::split(const string &s, vector<string> &elems) { 
    stringstream ss(s); 
    string item; 
    while(getline(ss, item, ',')) { 
     elems.push_back(item); 
    } 
    return elems; 
} 

Se está lanzando este error:

Manager.obj : error LNK2001: unresolved external symbol "private: static struct Vector Manager::airports" ([email protected]@@[email protected]@@@@A)

Manager.obj : error LNK2001: unresolved external symbol "private: static struct Vector Manager::flights" ([email protected]@@[email protected]@@@@A)

me doy cuenta que necesito para definir los vectores, pero ¿cómo ¿y donde? He intentado crear un constructor vacío y luego hacer

Manager::Manager() 
{ 
    vector<string> flights; 
    vector<string> airports; 
} 

Pero simplemente me dio un error de re-definición.

Respuesta

30

tiene que definir en el archivo .cpp:

vector<string> Manager::flights; 
vector<string> Manager::airports; 
+2

¿por qué son y no ? – conterio

23

En el archivo .cpp, es necesario agregar las definiciones de las variables estáticas:

vector<Airport> Manager::airports; 
vector<Flight> Manager::flights; 

Ver Why are classes with static data members getting linker errors? del FAQ C++.

+0

Oh no me daba cuenta que tenía que salir a la calle cualquier tipo de función o constructor – oliverw92

+1

Solo hay una instancia de una estática, por lo que ningún constructor sería apropiado. Es muy parecido a la forma en que declaras/defines las variables globales. P.ej. en el encabezado: 'extern int count;' y en el archivo fuente: 'int count = 0;'. (También tenga en cuenta que 'static 'tiene varios significados diferentes según dónde lo encuentre). –

5

Oli y Constantinius han respondido a su pregunta real, pero yo recomendaría cambiar la clase. Tal como está, solo tiene miembros estáticos, por lo que nunca puedes crear un objeto de esta clase. Si bien esto es legal C++, no está en el espíritu de C++ (aunque hay otros lenguajes que abarcan este uso, como C#)

Todos los miembros estáticos implican que estás intentando algún tipo de singleton, pero hay son formas más estándar de aplicar el singleton-ness de una clase.

Dicho esto - yo defiendo no edificio Singleton-dad en una clase. En su lugar, escriba la clase como una clase normal y proporcione un contenedor único. Esto también tiene el claro efecto secundario de evitar el notorio orden de inicialización fiasco que es probable que su código actual se tope.

Por lo tanto, algo así como (excluyendo la incluye por razones de brevedad):

Manager.h

class Manager { 
    vector<Airport> airports; 
    vector<Flight> flights; 
public: 
    Manager(); 
    void loadAirports(); 
    void loadFlights(); 
    Airport getAirport(string code); 
    vector<string> split(const string &s, vector<string> &elems); 
}; 

Manager& GetManager(); 

Manager.cpp

Manager::Manager() 
{ 
    loadAirports(); 
    loadFlights(); 
} 

Manager& GetManager() 
{ 
    static Manager manager; 
    return manager; 
} 
+0

Ah - y una nota al margen separada - si utiliza 'std :: set ' o 'std :: map ' en lugar de 'std :: vector ', puede evitar la búsqueda lineal en 'getAirport'. –

Cuestiones relacionadas