如何为头文件声明“#include”以避免“error lnk2005”



我创建了一个新的WIN32 C++项目。我还没有接触到主文件中的任何代码,而是开始在另一个文件objectsFW.cpp中编写代码,该文件的定义位于文件objectsFW.h中。

objFW.h看起来像:

#pragma once
double g;
typedef struct {
    double x;
    double y;
}Vector;
typedef struct {
    //...
}BoundingBox;
typedef struct {
    //...
}Ball;
Vector operator + (Vector a, Vector b) {
    //...
}
Vector operator - (Vector a, Vector b) {
    //...
}

还定义了一些运算符,以及函数的声明。我将头文件包含在源文件(objectsFW.cpp)中,并将其添加到Resources.h文件中,这样我的代码就可以在主程序中使用。

我得到链接器错误:

Error   1   error LNK2005: "struct Vector __cdecl operator*(struct Vector,double)" (??D@YA?AUVector@@U0@N@Z) already defined in ObjectsFW.obj   C:testCObjectsCollisionObjectsCollisionObjectsCollision.obj ObjectsCollision
...
Error   4   error LNK2005: "struct Vector __cdecl operator+(struct Vector,struct Vector)" (??H@YA?AUVector@@U0@0@Z) already defined in ObjectsFW.obj    C:testCObjectsCollisionObjectsCollisionObjectsCollision.obj ObjectsCollision

等等

我知道发生这种情况是因为#include "objectFW.h"行出现两次(每个.cpp文件中出现一次)。问题是,声明头文件以避免链接器错误的正确方法是什么?


更新:

在将操作员功能转到inline之后,大多数错误都得到了修复,仍然有一个带有以下行的程序:

double g;

错误是:

Error   1   error LNK2005: "double g" (?g@@3NA) already defined in ObjectsCollision.obj C:testCObjectsCollisionObjectsCollisionObjectsFW.obj    ObjectsCollision

(在Visual Studio 2012上工作)

关于全局变量:
1.不要使用它们。考虑封装数据隐藏
2.如果必须使用它们,请在1源文件中定义global,并将"extern"放在头文件中。

示例:
header_file.hpp:

  extern unsigned int deadly_global;

源文件.cpp:

  unsigned int deadly_global;

隐藏全局变量的更好方法

控制(隐藏)全局变量的更好方法是将使用该变量的所有代码放在同一源文件中,并将该变量声明为static:

  static unsigned int variable_shared_by_many_functions = 0;
  void f1(void)
  {
    variable_shared_by_many_functions = 42U;
  }
  void f2(void)
  {
    std::cout << "Value of shared variable: "
              << variable_shared_by_many_functions
              << "n";
  }

使用Getter和Setter控制全局变量

如果您必须在多个源文件中的函数之间共享变量,一种更安全的技术是在一个源文件中将变量声明为静态,并声明访问它的函数(接口)

  static int dangerous_variable = 0;
  int accessor(void)
  {
     // Return a copy of the varible.
     return dangerous_variable;
  }
  void setter(int new_value)
  {
    if ((new_value / 5) != 1)
    {
       dangerous_variable = new_value;
    }
  }

此技术允许您在设置变量时放置过滤器或其他控件。

放入标题:

extern double g;

在.cpp中:

double g;

这样,每个包含头的文件都会知道有一个变量g,但它只会在一个地方声明。

最新更新