我一直在尝试使用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");
}
的main.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 ++
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时都会发生多重定义。
我的问题是:
答案 0 :(得分:8)
为什么在定义后卫存在时
lib.h
多次被包含
您需要删除定义:
bool initialized = false;
并将其放在一个且只有一个源文件中。
包含防护措施可防止相同的头文件多次包含在同一 translation unit(TU) 中,而不是在不同的翻译单元中。
您可以在头文件中定义变量initialized
,该变量包含在不同的翻译单元中,然后每个TU都有一个名为initialized
的符号,用于打破 one definition rule 强>
我如何定义'extern'变量并在同一个文件中初始化它(因为它稍后在同一个文件中使用)
如果您希望变量在同一个文件中使用,为什么要将其变为extern
?如果要在不同的TU之间共享相同的变量,则需要使用extern
如果您只需要在单一TU中在全球范围内使用它,您应该简单地将其放在 unnamed namespace 中。