我试图实现一个用于图形操作的类。因此,我创建了两个文件graph.cc
和graph.h
。在完成头文件中的定义以及c ++文件中的实现之后,我使用了预处理程序指令#include "graph.h"
包含了graph.h。在执行命令g++ -I. -c graph.cc
之后,我得到了此编译错误消息:
graph.cc: In constructor ‘Graph::Graph(int)’:
graph.cc:4: error: ‘class Graph’ has no member named ‘adj’
graph.cc:4: error: expected type-specifier before ‘Neighbors’
graph.cc:4: error: expected ‘;’ before ‘Neighbors’
graph.cc:6: error: ‘adj’ was not declared in this scope
graph.cc:6: error: expected type-specifier before ‘Neighbors’
graph.cc:6: error: expected ‘;’ before ‘Neighbors’
我创建了两个文件test.cc
和test.h
,它们与以前的文件相同,但是include命令更改为#include "test.h"
。用于新文件的命令为g++ -I. -c test.cc
,并且编译成功,没有任何错误。
我认为以前的文件某种程度上包含了另一个来源的错误的graph.h
文件,因此我使用了这些命令在预处理阶段之后停止并查看两个版本之间的区别:
g++ -I. -E test.cc > out2.txt
g++ -I. -E graph.cc > out.txt
diff out.txt out2.txt
这是dif
的输出:
1c1
< # 1 "graph.cc"
---
> # 1 "test.cc"
4,5c4,5
< # 1 "graph.cc"
< # 1 "graph.h" 1
---
> # 1 "test.cc"
> # 1 "test.h" 1
23c23
< # 2 "graph.cc" 2
---
> # 2 "test.cc" 2
所以看来唯一的区别是文件名,其他所有内容都是相同的(我也检查了文本,它包含所有定义)。
sudo find / -iname "graph.h"
这是我尝试的最后一件事,除了创建的文件外,我什么都没找到。
在graph.cc文件中将#include "graph.h"
更改为#include "test.h"
可以解决此问题,但是我想知道为文件graph.h命名有什么问题?这可能与旧的g ++编译器有关,因为我尝试在计算机上重现该错误,但效果很好。
产生错误的g ++版本为g++ (Ubuntu 4.4.3-4ubuntu5.1) 4.4.3
这些是源代码。
graph.h
#ifndef _H_GRAPH
#define _H_GRAPH
template<class T>
class List{
public:
List(){}
List(int*){}
};
class Graph{
typedef List<int> Neighbors;
typedef Neighbors** AdjacencyList;
private:
AdjacencyList adj;
public:
Graph(int n);
};
#endif
graph.cc
#include "graph.h"
Graph::Graph(int n){
this -> adj = new Neighbors*[n];
for(int i = 0;i < n;i++)
adj[i] = new Neighbors((int*) 0);
}
test.h与graph.h相同。而test.cc和graph.cc之间的唯一区别是包含的文件。