5

我一直在尝试使用 extern 来使用先前定义的变量。

我以前没有使用过 extern,现在我需要使用它来定义变量一次并在多个文件中使用它们

我已经为这个问题编写了最小化版本的代码。我有四个文件

库文件

#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

车辆.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.cpp 的 vehicle.h 文件的实现

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

主文件

#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 时都会出现多个定义。

我的问题是:

  • 当定义保护存在时,为什么会多次包含 lib.h
  • 我将如何定义'extern'变量并在同一个文件中初始化它(因为它稍后在同一个文件中使用)
4

1 回答 1

8

为什么lib.h在定义保护时包含多次

您需要删除定义:

bool initialized = false;

并将其放在一个且只有一个源文件中。

包含保护可防止同一头文件多次包含在同一翻译单元 (TU)中,而不是在不同的翻译单元中。
您在头文件中定义变量,该变量initialized包含在不同的翻译单元中,然后每个 TU 都有一个名为的符号initialized,它违反了一个定义规则

我将如何定义'extern'变量并在同一个文件中初始化它(因为它稍后在同一个文件中使用)

如果您希望变量在同一个文件中使用,为什么要创建它externextern当您想在不同的 TU 之间共享相同的变量时需要使用。
如果您只需要在单个 TU 中在全局范围内使用它,您应该简单地将它放在一个未命名的命名空间中。

于 2013-01-26T06:38:18.600 回答