首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > VC/MFC >

添加了#ifndef为何还提示函数重复定义解决办法

2012-02-04 
添加了#ifndef为何还提示函数重复定义#ifndef _MY_H_ExpoGuide_Route_#define _MY_H_ExpoGuide_Route_#inc

添加了#ifndef为何还提示函数重复定义
#ifndef _MY_H_ExpoGuide_Route_
#define _MY_H_ExpoGuide_Route_


#include <iostream>
#include<CString>
using namespace std;
#define INFINITY 65535 //定义无穷大INFINITY
#define PlaceNum 20 //目前结点数(场馆+路口) 另:目前边数:53 场馆数:9



enum tag {UNVISITED,VISITED};

/*******************************************最小值堆*************************************************************/
//最小值堆
template <class Type>  
class MinHeap{  

private: 
Type * heapArr; 
int heapCurrentSize; 
int heapMaxSize; 
void FilterDown(const int start); 
void FilterUp(int p); 
public: 
MinHeap(int maxSize); 
MinHeap(Type a [], int n); 
~MinHeap(){
delete []heapArr;heapArr=NULL;

int Insert(const Type & d); 
Type DeleteTop(); 
Type GetTop() const{
return heapArr[0];

int IsEmpty(){
return heapCurrentSize == 0;

int IsFull() const{
return heapCurrentSize == heapMaxSize;

int SizeofHeap() const{
return heapCurrentSize;

void SetEmpty(){
heapCurrentSize = 0;


}; 

//最小值堆构造函数
template <class Type>
MinHeap<Type>::MinHeap(int maxSize){  
if (maxSize <= 0){ 
cerr << "The size of heap cannot be less than 1" << endl; 
exit(1); 

heapMaxSize = maxSize; 
heapArr = new Type[heapMaxSize]; 
heapCurrentSize = 0; 


//向下调整
template <class Type> 
void MinHeap<Type>::FilterDown(const int start){  
int i = start, j; 
Type temp = heapArr[i]; 
j = 2 * i + 1; 
while (j <= heapCurrentSize - 1){ 
if ((j < heapCurrentSize - 1) && (heapArr[j].length > heapArr[j+1].length)) 
j++; 
if (temp.length <= heapArr[j].length) 
break; 
else{ 
heapArr[i] = heapArr[j]; 
i = j; 
j = 2 * j + 1; 


heapArr[i] = temp; 



//向上调整
 
template <class Type>
void MinHeap<Type>::FilterUp(int p){  
int j = p, i;
Type temp = heapArr[j]; 
i = (j - 1) / 2; 
while (j > 0){ 
if (heapArr[i].length <= temp.length) 
break; 
else { 
heapArr[j] = heapArr[i]; 
j = i; i = (j - 1) / 2; 


heapArr[j] = temp; 


//插入
template <class Type>
int MinHeap<Type>::Insert(const Type & d){  
if (IsFull()) {
cout << "The heap is full" << endl; return 0;

heapArr[heapCurrentSize] = d; 
FilterUp(heapCurrentSize); 
heapCurrentSize++; 
return 1;





//删除堆顶最小元素
template <class Type>
Type MinHeap<Type>::DeleteTop(){  
if (IsEmpty()){ 
cout << "The heap is empty" << endl; 
 
}
else{
Type temp = heapArr[0]; 
heapArr[0] = heapArr[heapCurrentSize - 1]; 
heapCurrentSize--; 
FilterDown(0); 
return temp; 
}
}

/*******************************************图************************************************************************/

//边类
class Edge{  
public:
int from,to,weight;
//无参构造函数
Edge(){
from=-1;to=-1;weight=0;


}
//含参构造函数
Edge(int f,int t,int w){
from=f;
to=t;
weight=w;
}
};


//图基类
class Graph{  
public:
int numVertex; //顶点数
int numEdge; //边数
int *Mark; //标志矩阵

//含参构造函数
Graph(int numVert){
numVertex=numVert;
numEdge=0;
Mark=new int[numVertex];
for(int i=0;i<numVertex;i++){
Mark[i]=UNVISITED;
}
}

Graph(){};
//析构函数
~Graph(){
delete[]Mark;
}
//判断是否为一条边
bool IsEdge(Edge oneEdge){  
if((oneEdge.weight>0) && (oneEdge.weight<INFINITY))
return true;
return false;
}
//返回顶点个数
int VerticesNum(){return numVertex;}
//返回边数
int EdgesNum() {return numEdge;}
  //返回某条边的终点
int ToVertex(Edge oneEdge){  
return oneEdge.to;
}
};


//邻接矩阵图类
class Graphm:public Graph{  
private:
int **matrix;  

public:
char **name; //保存结点名称的二维数组

//含参构造函数
Graphm(int numVert):Graph(numVert){
int i,j;
//为二维数组matrix开空间
matrix=(int**)new int*[numVertex];
for(i=0;i<numVertex;i++)
matrix[i]=new int[numVertex];
   
//初始化二维数组
for(i=0;i<numVertex;i++)
for(j=0;j<numVertex;j++){
if(i==j)
matrix[i][j]=0;
else
matrix[i][j]=INFINITY;
}
  //为二维数组name开空间
name=new char*[numVertex];
for(i=0;i<numVertex;i++)
name[i]=new char[30];

}

Graphm(){};

//析构函数
~Graphm(){
//释放matrix二维数组空间
if (matrix){
for(int i=0;i<numVertex;i++){
delete[]matrix[i];
matrix[i]=NULL;
}
delete[]matrix;
matrix=NULL;
}

//释放name二维数组空间
if (name){
for(int i=0;i<numVertex;i++){
delete[]name[i];
name[i]=NULL;
}
delete[]name;
name=NULL;
}
}




//返回依附于某顶点的第一条边
Edge FirstEdge(int oneVertex){
Edge myEdge;
myEdge.from=oneVertex;
for(int i=0;i<numVertex;i++){
if((matrix[oneVertex][i]!=0) && (matrix[oneVertex][i]<INFINITY)){
myEdge.to=i;
myEdge.weight=matrix[oneVertex][i];
break;
}
}
return myEdge;
}

//返回下一条边
Edge NextEdge(Edge preEdge){
Edge myEdge;
myEdge.from=preEdge.from;
if(preEdge.to<numVertex){
for(int i=preEdge.to+1;i<numVertex;i++){

if((matrix[preEdge.from][i]!=0) && (matrix[preEdge.from][i]<INFINITY)){
myEdge.to=i;
myEdge.weight=matrix[preEdge.from][i];
break;
}

}
}
return myEdge;
}
 
  //设置一条边
void SetOneEdge(int from,int to,int w){
if(matrix[from][to]>=INFINITY){ //如果此边不存在
numEdge++;
matrix[from][to]=w;
matrix[to][from]=w;
}
}


   

};

/*************************************************图设置函数*************************************************************/

  //设置结点名称
  void SetName(Graphm &G){  
strcpy(G.name[0],"世博大道-白莲泾路");
strcpy(G.name[1],"世博大道-高科西路");
strcpy(G.name[2],"世博大道-上南路");
strcpy(G.name[3],"博成路-白莲泾路");
strcpy(G.name[4],"博成路-高科西路");
strcpy(G.name[5],"博成路-云台路");
strcpy(G.name[6],"博成路-上南路");
strcpy(G.name[7],"国展路-白莲泾路");
strcpy(G.name[8],"国展路-高科西路");
strcpy(G.name[9],"国展路-云台路");
strcpy(G.name[10],"国展路-上南路");


strcpy(G.name[11],"中国馆");
strcpy(G.name[12],"日本馆");
strcpy(G.name[13],"马尔代夫馆");
strcpy(G.name[14],"以色列馆");
strcpy(G.name[15],"阿富汗馆");
strcpy(G.name[16],"印度馆");
strcpy(G.name[17],"台湾馆");
strcpy(G.name[18],"澳门馆");
strcpy(G.name[19],"香港馆");
}


  //设置所有边(以excel文档矩形下三角为准)
void SetAllEdges(Graphm &G){
G.SetOneEdge(0,1,280);
G.SetOneEdge(0,3,150);
G.SetOneEdge(0,12,150);

G.SetOneEdge(1,2,400);
G.SetOneEdge(1,4,150);
G.SetOneEdge(1,16,160);

G.SetOneEdge(2,6,180);
G.SetOneEdge(2,16,160);
G.SetOneEdge(2,17,180);

G.SetOneEdge(3,4,280);
G.SetOneEdge(3,7,220);
G.SetOneEdge(3,12,10);
G.SetOneEdge(3,13,220);

G.SetOneEdge(4,5,350);
G.SetOneEdge(4,8,290);
G.SetOneEdge(4,12,280);
G.SetOneEdge(4,15,100);
G.SetOneEdge(4,16,210);

G.SetOneEdge(5,6,180);
G.SetOneEdge(5,9,280);
G.SetOneEdge(5,14,190);
G.SetOneEdge(5,15,250);
G.SetOneEdge(5,16,240);
G.SetOneEdge(5,17,180);

G.SetOneEdge(6,10,330);
G.SetOneEdge(6,11,330);
G.SetOneEdge(6,17,10);
G.SetOneEdge(6,18,330);
G.SetOneEdge(6,19,330);

G.SetOneEdge(7,8,290);
G.SetOneEdge(7,12,220);
G.SetOneEdge(7,13,10);

G.SetOneEdge(8,9,360);
G.SetOneEdge(8,13,290);
G.SetOneEdge(8,14,360);

G.SetOneEdge(9,10,390);
G.SetOneEdge(9,11,300);
G.SetOneEdge(9,14,240);
G.SetOneEdge(9,18,390);
G.SetOneEdge(9,19,390);

G.SetOneEdge(10,11,60);
G.SetOneEdge(10,17,330);
G.SetOneEdge(10,18,10);
G.SetOneEdge(10,19,10);

G.SetOneEdge(11,17,330);
G.SetOneEdge(11,18,60);
G.SetOneEdge(11,19,60);

G.SetOneEdge(12,13,220);

G.SetOneEdge(14,15,150);

G.SetOneEdge(15,16,100);

G.SetOneEdge(17,18,330);
G.SetOneEdge(17,19,330);

G.SetOneEdge(18,19,10);
}




/*******************************************图算法******************************************************************/
//Dist 类
class Dist{  
public:
int index;
int length;
int pre;
};



//Floyd算法
 void Floyd(Graphm &G,Dist**& D){
  int i,j,v;
D=new Dist*[G.VerticesNum()];
for(i=0;i<G.VerticesNum();i++)
D[i]=new Dist[G.VerticesNum()];
//初始化二维数组,点到自身路径长度为0,其余为无穷
for(i=0;i<G.VerticesNum();i++)
for(j=0;j<G.VerticesNum();j++){
if(i==j){
D[i][j].length=0;
D[i][j].pre=i;
}
else{
D[i][j].length=INFINITY;
D[i][j].pre=-1;
}
}
for(v=0;v<G.VerticesNum();v++)
for(Edge e=G.FirstEdge(v);G.IsEdge(e);e=G.NextEdge(e)){
D[v][G.ToVertex(e)].length=e.weight;
  D[v][G.ToVertex(e)].pre=v;
}
for(v=0;v<G.VerticesNum();v++)
for(i=0;i<G.VerticesNum();i++)
for(j=0;j<G.VerticesNum();j++)
if(D[i][j].length>(D[i][v].length+D[v][j].length)){
D[i][j].length=D[i][v].length+D[v][j].length;
D[i][j].pre=D[v][j].pre;
}

   
}

#endif


我的工程中有这个.h头文件,编译通过,运行的时候报错:
ExpoGuideDlg.obj : error LNK2005: "void __cdecl SetName(class Graphm &)" (?SetName@@YAXAAVGraphm@@@Z) already defined in ExpoGuide.obj
ExpoGuideDlg.obj : error LNK2005: "void __cdecl SetAllEdges(class Graphm &)" (?SetAllEdges@@YAXAAVGraphm@@@Z) already defined in ExpoGuide.obj
ExpoGuideDlg.obj : error LNK2005: "void __cdecl Floyd(class Graphm &,class Dist * * &)" (?Floyd@@YAXAAVGraphm@@AAPAPAVDist@@@Z) already defined in ExpoGuide.obj


Debug/ExpoGuide.exe : fatal error LNK1169: one or more multiply defined symbols found
Error executing link.exe.

说SetName SetAllEdges Floyd这三个函数重复定义,但是我已经加了#ifndef...之类的东西了,不明白为什么还报错,而且只报这三个函数而不报其他的类?




[解决办法]
你的用法应该没有问题,这一点我也一直很困惑,等待高手解答。

对于你程序中报出的错误,可以在那三个函数定义前加static 或 extern解决。
[解决办法]
外部头文件里面的函数,每次在当前的cpp里面引用,都会试图生成一个新的符号地址,这样子连接时符号名就重了,也就报重复定义。 改成static之后, 就会固定一个静态地址,这样子就不会出现上述情况。
[解决办法]
接楼上: 
.obj就是编译好的中间文件,lz给出的错误信息就是对这些中间文件连接时发生的。

热点排行