包含g ++标头:仍然找不到定义

时间:2009-03-22 04:13:54

标签: c++ include makefile g++ header-files

晚上好:)

我正在玩g ++和makefile。我已经到了这一步:

foo.h中:

#ifndef _FOO_H_
#define _FOO_H_

#include "bar.h"

class foo {
private:
    bar something;
public:
    bool start();
    bool stop();
};

#endif // _FOO_H_

Foo.h最终包含在我的主cpp文件中,所以我可以通过调用start / stop来设置动作。

void somewhere() {
    foo* hihi = new foo;
    hihi->start();
    delete hihi;
}

然后是bar.h:

#ifndef _BAR_H_
#define _BAR_H_

class bar {

};

#endif // _BAR_H_


然而,g ++似乎并不喜欢它:

g++  (some_flags) -c main.cpp
In file included from main.cpp:2:
foo.h:8: error: ‘bar’ does not name a type

我正在使用makefile,并尝试了以下各项的组合:

main.o: main.cpp foo.h bar.h

即使我认为我不应该在这里添加bar.h,但是不应该将它包含在foo.h中吗?

澄清一下,这大致是现在如何设置(是的,我知道这可以以更有效的方式完成):

main.o: main.cpp foo.h
    $(CC) $(CFLAGS) -c main.cpp

foo.o: foo.h foo.cpp
    $(CC) $(CFLAGS) -c foo.cpp

bar.o: bar.h bar.cpp
    $(CC) $(CFLAGS) -c bar.cpp

发生了什么事?我认为这是我缺少的关于g ++及其处理标题的方式,请指出正确的方向!

编辑 - 找到解决方案:

卫生署!我现在感到愚蠢。 正在乱搞boost :: asio,有点忘了我仍然把它放在我的标题上: 使用boost :: asio :: ip :: tcp;

我们只是说有一个提升:: asio :: ip :: tcp :: bar功能:D

哦,好吧,谢谢!

4 个答案:

答案 0 :(得分:2)

仔细检查一切。如果将bar.h包含到foo.h中,则编译器不应引发错误。你是否包含foo.h的{​​{1}}?最好不要这样做,因为这会导致标头之间的循环依赖,这将导致这种错误。

同时检查标题警卫的拼写。这可能是烦恼的常见原因:

bar.h

此外,您应该避免在标题保护宏名称之前添加下划线。这些名称保留给编译器。称之为#ifdef _BAR_H_ // OOPS! we wanted #ifndef #define _BAR_H_ class bar { }; #endif // _BAR_H_ 或仅INCLUDED_BAR_H

答案 1 :(得分:2)

  

正在乱搞boost :: asio,有点忘了我仍然把它放在我的标题之上:使用boost :: asio :: ip :: tcp;

     

我们只是说有一个boost :: asio :: ip :: tcp :: bar函数

Dan Saks explains为什么你应该输入你的类名来解决一些原因,即使它看起来多余。

嗯,你已经遇到了现实生活中的情况,在这种情况下,对一个类进行打字可能会帮助你更轻松地找到问题:

 class bar {
 // ...
 };
 typedef class bar bar;

如果已经声明了名为bar()的函数,则生成这个更有意义的消息:

In file included from C:\temp\foo.h:4,
                 from C:\temp\test.cpp:4:
C:\temp\bar.h:7: error: `typedef class bar bar' redeclared as different kind of symbol
C:\temp\test.cpp:1: error: previous declaration of `void bar(int)'
C:\temp\bar.h:7: error: declaration of `typedef class bar bar'

答案 2 :(得分:1)

Tommy Hui和litb已经指出了两个可能的原因;这里有一些背景信息,希望有用。

首先,这与makefile无关。 makefile只是为你调用g ++的便利之处,仅此而已。

这个带有头文件的东西起初可能有点难以理解,特别是一旦你进入循环依赖。这真的帮助我实现了这三件事:

  • #include只不过是一个复制/粘贴操作,此时插入所包含文件的内容。
  • 在使用之前,所有内容都必须声明。有时,当循环依赖关系出现时,您可能需要在另一个标题中预先声明一个类(例如class bar;)。
  • 如果在使用时,需要有关该类型的更多信息而不仅仅是它的存在,那么也需要类型的定义。这适用于例如在该类型的对象上调用方法,但也包括该类型的字段! (但不是指向那种类型的对象的指针,因为指针的大小都相同。)

答案 3 :(得分:0)

在main.cpp中,您需要在文件顶部添加以下行:

#include "foo.h"