2013-01-26 13 views
5

Ho cercato di utilizzare extern per utilizzare la variabile che è stata precedentemente definita.la variabile extern causa l'errore a più definizioni

Non ho usato extern prima e ora ho bisogno di usarlo per definire variabili solo una volta e li usa in più file

ho scritto versione ridotta di codice per questa domanda. Ho quattro file

lib.h

#ifndef LIB_H 
#define LIB_H 

#include <iostream> 

namespace lib { 

    extern bool initialized; 

    bool initialized = false; 

    static void isInit(char* parent) { 
    std::cout << "Library for [" << parent << "] initialized? " << (::lib::initialized ? "yes" : "no") << "\n"; 
    } 
} // namespace lib 
#endif 

vehicle.h

#ifndef _VEHICLE_H 
#define _VEHICLE_H 
#include <string> 

class Vehicle { 
    public: 
    Vehicle(const std::string& manufacturer, 
      const std::string& model, 
      int year); 
    std::string manufacturer; 
    std::string model; 
    int year; 
}; 
#endif 

In seguito è la realizzazione di file di vehicle.h chiamato vehicle.cpp

#include "vehicle.h" 

#include "lib.h" 

Vehicle::Vehicle(const std::string& manufacturer, 
       const std::string& model, 
       int year) : 
        manufacturer(manufacturer), 
        model(model), 
        year(year) { 
    ::lib::isInit("Vehicle"); 
} 

principale .cpp

#include "vehicle.h" 

#include "lib.h" 

int main(int argc, char** argv) { 

    ::lib::isInit("main"); 

    ::lib::initialized = true; 

    ::lib::isInit("main"); 

    Vehicle vehicle("Toyota", "Corolla", 2013); 

    return 0; 
} 

Sto usando g ++

g++ -Wno-write-strings main.cpp vehicle.cpp -o bin/main.cpp.bin 

ottengo seguenti errori:

/tmp/cclVpsgT.o:(.bss+0x0): multiple definition of `lib::initialized' 
/tmp/ccmJKImL.o:(.bss+0x0): first defined here 
collect2: error: ld returned 1 exit status 

Ho controllato l'output di:

g++ -Wno-write-strings main.cpp vehicle.cpp -E 

definizione multipla si verifica ogni volta lib.h è incluso.

Le mie domande sono:

  • Perché lib.h incluso più volte quando definire guardia c'è
  • Come definirei 'extern' variabile e inizializzare nello stesso file (dal momento che è utilizzato in lo stesso file in seguito)

risposta

8

Perché lib.h incluso più volte quando definire guardia c'è

è necessario rimuovere la definizione:

bool initialized = false; 

e metterlo in uno e un solo file sorgente.

Includere guardie impediscono lo stesso file di intestazione di ottenere incluso più di una volta nella stessa translation unit(TU) non in diverse unità di traduzione.
si definisce la variabile initialized nel file di intestazione, che viene incluso tra le varie unità di traduzione e poi ognuno TU ha un simbolo denominato initialized che rompe la one definition rule.

Come dovrei definire 'extern' variabile e inizializzare nello stesso file (dal momento che è usato nello stesso file in seguito)

Se si desidera la variabile da utilizzare nella stessa file, perché renderlo extern? È necessario utilizzare extern quando si desidera condividere la stessa variabile su diverse TU.
Se avete bisogno di usarlo in ambito globale in unico singolo TU, si dovrebbe semplice metterlo all'interno di un unnamed namespace.

+0

non c'è modo di farlo nello stesso file? – abumusamq

+0

@ mkhan3189: La risposta alla seconda domanda risponde alla Q nel tuo commento? –

+0

Sì, lo fa :) contrassegnando questo come risposta poiché questo risponde alla mia domanda. Credo che non ci sia modo di inizializzare nello stesso file poiché è esterno. – abumusamq

Problemi correlati