2013-01-26 6 views
5

Я пытаюсь использовать extern для использования переменной, которая была определена ранее.Внешняя переменная вызывает множественную ошибку определения

Я не использовал EXTERN раньше, а теперь мне нужно использовать его для того, чтобы определить переменный только один раз и использовать их в нескольких файлах

Я написал свернутую версию коды для этого вопроса. У меня есть четыре файла

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 

Ниже приводится реализация vehicle.h файла называется 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"); 
} 

основной .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; 
} 

Я использую г ++

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

я получаю следующие ошибки:

/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 

Я проверил вывод:

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

множественного определения происходит каждый раз, когда lib.h Включено.

Мои вопросы:

  • Почему lib.h включено несколько раз, когда определяют охрану там
  • Как бы определить «Экстерн» переменной и инициализировать его в том же файле (так как он используется в тот же файл позже)

ответ

8

Почему lib.h включено несколько раз, когда определяют охрану там

Вам нужно удалить определение:

bool initialized = false; 

И поставить его в один и только один исходный файл.

Включите охранники предотвратить один и тот же файл заголовка от получать более одного раза в одной и той же translation unit(TU) не в разных единицах трансляции.
Вы определяете переменную initialized в заголовочном файле, который получает включен в разных единицах трансляции, а затем каждый TU имеет символ с именем initialized, который ломает one definition rule.

Как бы определить «Экстерн» переменной и инициализировать его в том же файле (так как он используется в том же файле позже)

Если вы хотите, чтобы переменная будет использоваться в том же файл, зачем делать его extern? Вам нужно использовать extern, если вы хотите использовать одну и ту же переменную в разных TU.
Если вам нужно использовать его в глобальном масштабе только в одном TU, вы должны просто положить его внутри unnamed namespace.

+0

Нет ли способа сделать это в одном файле? – abumusamq

+0

@ mkhan3189: Отвечает ли ответ на второй вопрос Q в вашем комментарии? –

+0

Да, это так :) отмечая это как ответ, так как это отвечает на мой вопрос. Я считаю, что нет способа инициализировать в том же файле, поскольку это extern. – abumusamq