最近,我在mac os上编译libfacebookcpp。我发现了一个我无法理解的奇怪用法。 有两个文件,AuthorizedObject.hpp和List.hpp。 在文件AuthorizedObject.hpp的末尾,有一行:#include“List.hpp”。现在我编译成功。但 当我将该行移动到开头时,会发生错误。代码的骨架是:
//AuthorizedObject.hpp
class AuthorizedObject
{
public:
...
template<class TType>
void _GetConnection(const ::std::string& uri, List<TType> *list) const
{
LIBFACEBOOKCPP_CHKARG(list);
Json::Value value;
request_->GetResponse(uri, &value);
list->Deserialize(*this, value);
}
...
}
#include "List.hpp" //end
----------------------------------------------------------
//List.hpp
#include "AuthorizedObject.hpp"
class LIBFACEBOOKCPP_API List : public AuthorizedObject
{
private: // private classes
...
}
我想如果将该行(#include“List.h”)放在AuthorizedObject.hpp的开头,则这两个文件按圆圈互相包含。所以编译器不知道怎么编译。但是把那行放到最后会解决这个问题吗?为什么?提前谢谢。
答案 0 :(得分:1)
不同之处在于定义了类/函数/ ...的顺序,例如:
#include "one.h"
void foo(bar &);
// Will result into:
class bar {};
void foo(bar&);
哪个是有效代码。另一方面:
void foo(bar &);
#include "one.h"
// Will result into statements in different order:
void foo(bar&);
class bar {};
这意味着在声明之前使用class bar
,因此出错。您还可能需要确保不会处理两次声明(UmNyobe already covered that partially):
#if !defined( MY_HEADER_INCLUDED_)
# define MY_HEADER_INCLUDED_
// Complete content goes here
#endif /* !defined( MY_HEADER_INCLUDED_) */
这样,当您第一次包含文件时,将不会定义MY_HEADER_INCLUDED_
(内容将被“放置”在代码中)。第二次(您将其包含在圆圈中)将定义MY_HEADER_INCLUDED_
,因此将跳过完整的正文。
答案 1 :(得分:1)
你是对的,这就是问题所在。你错了,编译器不知道如何编译 - 它确实如此,你只是错误地使用它:)。
AuthorizedObject.hpp
开头的包含警卫(我假设它包含警卫或#pragma once
指令)将定义AUTHORIZED_OBJECT_H
(或类似)。之后,您加入List.h
,其中又包含标题AuthorizedObject.hpp
。由于已经定义了包含保护宏,因此跳过AuthorizedObject
的定义,因此List
不知道类型,但是使用它,因此您会收到错误。
如果你在最后移动了include,那么编译器已经处理了AuthorizedObject
的定义,因此在List.h
中使用它是有效的。