6

我有一个头文件“USpecs.h”:

#ifndef USPECS_H
#define USPECS_H
#include "Specs.h"


#include <iostream>
#include <vector>

std::vector<Specs*> UcakSpecs;


#endif

我在主函数和另一个名为 Ucak 的类中都使用了这个头文件。

但是当我构建它时,会发生以下错误:

Ucak.cpp|6|`UcakSpecs'的多重定义|

正如我之前搜索的那样,#ifndef 应该没问题,但事实并非如此。

4

3 回答 3

8

包含防护仅防止在单个翻译单元(即具有包含的标头的单个源文件)中的多个定义。当您包含来自多个源文件的标头时,它们不会阻止多个定义。

相反,您应该在标题中声明:

extern std::vector<Specs*> UcakSpecs;

以及一个(也是唯一一个)源文件中的定义:

std::vector<Specs*> UcakSpecs;
于 2013-04-02T13:37:38.697 回答
4

包含保护仅防止标头多次包含在同一翻译单元中。如果您在多个翻译单元中包含此标题,您将在UcakSpecs整个程序中有多个定义。

声明全局变量的方法是extern在头文件中声明它:

#ifndef USPECS_H
#define USPECS_H
#inclde "Specs.h"


#include <iostream>
#include <vector>

extern std::vector<Specs*> UcakSpecs;

#endif

声明为的全局变量extern只是一个声明。

然后通过在实现文件中定义它来确保它只在单个翻译单元中定义(可能在 中USpecs.cpp);

std::vector<Specs*> UcakSpecs;
于 2013-04-02T13:37:10.753 回答
3

仅适用于#ifndef单个编译单元。由于您有两个(主函数和Ucak类),因此该变量被定义了两次。

考虑extern在头文件中声明变量:

extern std::vector<Specs*> UcakSpecs;

并在Ucak.cpp文件中定义它:

std::vector<Specs*> UcakSpecs;

这应该有效。

于 2013-04-02T13:37:32.430 回答