简体   繁体   English

包括 g++ header:仍然找不到定义

[英]g++ header included: still doesn't find definition

Good evening:)晚上好:)

I'm playing around with g++ and makefiles.我在玩 g++ 和 makefile。 I've gotten to this point:我已经到了这一点:

foo.h:富.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 is eventually included in my main cpp file so I can set things in motion by calling start/stop. Foo.h 最终包含在我的主 cpp 文件中,因此我可以通过调用 start/stop 来启动。

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

Then there's bar.h:然后是bar.h:

#ifndef _BAR_H_
#define _BAR_H_

class bar {

};

#endif // _BAR_H_


g++ doesn't seem to like it however: g++ 似乎并不喜欢它:

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

I'm using makefiles, and tried a combination of things like:我正在使用makefile,并尝试了以下组合:

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

Even though I don't think I should have to add bar.h here, shouldn't including it in foo.h be enough?尽管我认为我不应该在这里添加 bar.h,但不应该将它包含在 foo.h 中就足够了吗?

To clarify, this is roughly how it's set up now (yes I know this can be done in a more efficient manner):为了澄清,这大致是它现在的设置方式(是的,我知道这可以以更有效的方式完成):

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

What's going on?这是怎么回事? I figure it's something I'm missing about g++ and the way it handles header includes, point me in the right direction please!我认为这是我对 g++ 及其处理 header 的方式所缺少的东西,请指出我正确的方向!

edit - found the solution:编辑 - 找到解决方案:

Doh.多哈。 I feel dumb right now: Was messing around with boost::asio and kind of forgot I still left this on top of my headers somewhere: using boost::asio::ip:;tcp;我现在感觉很愚蠢:在搞乱 boost::asio 并且有点忘记了我仍然把这个放在我的标题上的某个地方:使用 boost::asio::ip:;tcp;

Let's just say there's a boost::asio::ip::tcp::bar function:D假设有一个 boost::asio::ip::tcp::bar function:D

Oh well, thanks anyway!哦,好吧,还是谢谢!

Double check everything.仔细检查一切。 If you include bar.h into foo.h , the compiler should not raise up an error.如果将bar.h包含到foo.h中,编译器不应引发错误。 Do you include foo.h from bar.h ?您是否包含来自bar.hfoo.h Better don't do this because that would cause a circular dependency between headers, which will cause that kind of bugs.最好不要这样做,因为这会导致标题之间的循环依赖,这将导致那种错误。

Also check for spelling of header guards.还要检查 header 防护装置的拼写。 This can be a common source of annoyance:这可能是一个常见的烦恼来源:

#ifdef _BAR_H_ // OOPS! we wanted #ifndef
#define _BAR_H_

class bar {

};

#endif // _BAR_H_

In addition, you should avoid putting the underscore before your header guard macro name.此外,您应该避免在 header 保护宏名称之前放置下划线。 These names are reserved to the compiler.这些名称保留给编译器。 Call it INCLUDED_BAR_H or just BAR_H_ instead.将其称为INCLUDED_BAR_H或仅BAR_H_

Was messing around with boost::asio and kind of forgot I still left this on top of my headers somewhere: using boost::asio::ip::tcp;正在搞乱 boost::asio 并且有点忘记了我仍然把这个放在我的标题顶部的某个地方:使用 boost::asio::ip::tcp;

Let's just say there's a boost::asio::ip::tcp::bar function假设有一个 boost::asio::ip::tcp::bar function

Dan Saks explains some reasons why you should typedef your class names, even though it might seem redundant. Dan Saks 解释了为什么您应该 typedef 您的 class 名称的一些原因,即使它看起来可能是多余的。

Well, you've run into real life situation where typedefing a class would have probably helped you find your problem a little easier:好吧,您已经遇到了现实生活中的情况,其中定义 class 可能会帮助您更轻松地找到问题:

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

Generates this more meaningful message if there's a function named bar() already declared:如果已经声明了名为bar()的 function,则生成此更有意义的消息:

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'

Tommy Hui and litb have already pointed to two probable causes; Tommy Hui 和 litb 已经指出了两个可能的原因; here's some background information that will hopefully come in useful.这里有一些背景信息,希望能派上用场。

First off, this has nothing to do with makefiles.首先,这与makefile 无关。 A makefile is just a convenience thing that calls g++ for you, nothing more. makefile 只是一个方便的东西,它为您调用 g++,仅此而已。

This stuff with header files can be a bit tricky to understand at first, especially once you get into circular dependencies. header 文件的这些东西起初可能有点难以理解,尤其是当你陷入循环依赖时。 It really helped me to realize these three things:它确实帮助我意识到了这三件事:

  • A #include is nothing more than a copy/paste operation, inserting the contents of the included file at that point. #include只不过是一个复制/粘贴操作,在该点插入包含文件的内容。
  • Everything must have been declared before it is used.一切都必须在使用前声明 Sometimes, when circular dependencies crop up, you might need to predeclare a class (eg class bar; ) in another header.有时,当循环依赖出现时,您可能需要在另一个 header 中预先声明一个 class(例如class bar; )。
  • If, at the point of usage, any more information about the type is needed than just its existence, then the type's definition is needed as well.如果在使用时需要关于类型的更多信息而不仅仅是它的存在,那么还需要类型的定义 This goes for eg calling of a method on an object of that type, but also for including a field of that type, (Not for a pointer to an object of that type, though. because pointers are all the same size.)例如,这适用于在该类型的 object 上调用方法,但也适用于包含该类型的字段(但不适用于指向该类型的 object 的指针。因为指针的大小都相同。)

In the main.cpp, you'll need to add the following line at the top of the file:在 main.cpp 中,您需要在文件顶部添加以下行:

#include "foo.h"

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM