2016-07-29 69 views
0

我的第一个,眼前的问题是,看起来像这么多奇怪的错误:C++:奇怪的多个定义的错误和问题

In function ZN6BeingC2Ev: 
multiple definition of 'area' 
first defined here 

我写一个基本的寻路系统,我有两个类:

-区域:区域描述了穿过墙壁和开放空间的2D网格。每一个能够寻路的人都有自己的图,每个图对象都需要从当前活动的区域中获取世界网格的一部分布局。因此,所有Graph对象都需要知道* area,它在main()中是由通常的area = new Area()分配的。

但是我无法在main.cpp中声明Area *区域,因为Graphs将无法看到它,并且其方法将无法读取它。

所以我试图在area.h中声明*区域(如下所示)。我的意图是,因为Graph#包含“area.h”,所以Graph将知道该区域。这会导致我的多重定义问题。

我不确定究竟是什么问题,因为我确定我没有在其自己的头文件之外以任何方式定义Area,部分原因是当我单击错误消息的时候,我的IDE指向我看似无关的函数多重定义的来源。

所以我的第二个问题:为了避免出现这样的错误,是否有更好的结构可以让Graph知道Area对象并访问它们的内容?

下面是代码,我希望证明我的意图,请让我知道是否有必要的东西已被省略。

area.h

#ifndef AREA_H_INCLUDED 
#define AREA_H_INCLUDED 

class Area 
{ 
    std::vector<int>wallmap; 
    ... 
} *area; 

#endif // AREA_H_INCLUDED 

graph.h

#ifndef GRAPH_H_INCLUDED 
#define GRAPH_H_INCLUDED 

#include "area.h" 

class Graph 
{ 
    ... 
}; 

#endif // GRAPH_H_INCLUDED 

graph.cpp(该问题是在开关部)

std::vector<Node*>Graph::RequestPath(int startX, int startY, int destX, int destY); 
{ 
    for(std::vector<Node*>::iterator it = nodeGraph.begin(); it != nodeGraph.end(); ++it) 
    { 
     (*it)->heuristic = std::abs(destX-startX) + std::abs(destY-startY); 

     switch(area->wallmap[(*it)->id]) // **I need Graphs to know about the wallmap vector in Area, here for example.** 
     { 
      .... 
     } 

    (*it)->fValue = (*it)->heuristic + (*it)->moveCost; 
    } 
} 

的main.cpp

#include "area.h" 

int main() 
{ 
    ... 
    area = new Area(); 
    area->Init(); 

    ... 
    delete area; 
    ... 
} 

感谢您的协助!

+1

只是表明你的意图的代码不太可能证明你的问题*除非你的意图是根本错误的。我们需要一个[mcve]在这里。 – user2357112

+3

您正在头文件中定义一个全局变量,并且包含它的每个翻译单元(cpp文件)都将获取此变量的一个副本。不要在头文件中定义全局变量。实际上,尽量不要使用全局变量。 – GManNickG

+0

'ZN6BeingC2Ev'看起来不像格式正确的GCC-mangled名称。 '2'后面至少有两个字符丢失。我同意在这里需要一个MCVE,但除此之外,还有*实际的错误消息*,而不是“看起来像”这样的单词。 – 2016-07-29 21:22:04

回答

4

为在@GManNickG评论指出,问题在于使用area作为一个变量:

class Area 
{ 
    std::vector<int>wallmap; 
    ... 
} *area; 

每个编译单元#include S中的.h文件中会定义一个变量,导致链接时发生多重定义错误。

我建议使用一个函数来获取必要的指针,而不是使用全局变量。

class Area 
{ 
    std::vector<int>wallmap; 
    ... 
}; 

Area* getArea(); 

实现它在。cpp文件,它实现了Area的成员函数,只是为了将相关定义保存在一起

然后,无论您使用的是全局变量,都可以使用该函数。

如果必须使用全局变量,我强烈建议你,你可以使用:

class Area 
{ 
    std::vector<int>wallmap; 
    ... 
}; 

extern Area* area; 

,并确保area在实现的Area成员函数.cpp文件中定义,只是将相关定义保持在一起。