2013-01-26 21 views
5

Önceden tanımlanmış bir değişken kullanmak için extern kullanmaya çalışıyorum.extern değişkeni çok tanımlı bir hataya neden oluyor

Daha önce extern kullanmadıysanız ve şimdi sadece bir kez değişken tanımlamak ve birden fazla dosya

Bu soru için kod minimize versiyonunu yazdım

karşısında bunları kullanmak için bunu kullanmak gerekir. İzlediğim

#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 

lib.h dört dosya

sahip

#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"); 
} 

ana vehicle.cpp denilen vehicle.h dosyasının uygulamasıdır .cpp

Ben çıktısını kontrol ettikten

/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 

birden tanımı her zaman lib.h oluşur ben g ++

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

kullanıyorum

#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; 
} 

Ben aşağıdaki hataları olsun içerir.

Sorularım şunlardır:

  • neden olduğunda bekçi tanımlamak lib.h birden çok kez dahil olan orada
  • ı tanımlamak 'extern' değişken ve kullanılan beri (aynı dosyada bunu başlatmak istiyorum nasıl
  • nöbet tanımlarken lib.h birden çok kez dahil Neden sonra aynı dosya)

cevap

8

yoktur

bool initialized = false; 

Ve birinde koymak ve sadece tek bir kaynak dosyası:

Tanımı kaldırmak gerekir.

korumalar değil, farklı çeviri birimleri aynı translation unit(TU) kereden fazla dahil olma aynı başlık dosyasını önlemek ekleyin.
Farklı çeviri birimlerinde dahil olur başlık dosyasında değişken initialized tanımlar ve ardından her TU one definition rule kırar initialized adında bir sembol vardır.

nasıl 'extern' değişken tanımlamak ve (daha sonra aynı dosyada kullanılan beri) değişken aynı kullanılacak istiyorsanız aynı dosyada

bunu başlatmak istiyorum dosya, neden extern? Aynı değişkeni farklı TU'larla paylaşmak istediğinizde extern'u kullanmanız gerekir.
Küresel kapsamda yalnızca tek bir TU'da kullanmanız gerekirse, bunu unnamed namespace içine koymanız gerekir.

+0

Aynı dosyada bunu yapmanın bir yolu yok mu? – abumusamq

+0

@ mkhan3189: Yorumunuzdaki ikinci soruya cevap Q'ya cevap veriyor mu? –

+0

Evet, bunu cevap olarak işaretliyorum :) çünkü bu soruya cevap veriyor. Ben extern beri aynı dosyada başlatmak için bir yol olduğuna inanıyorum. – abumusamq

İlgili konular