1

最近,我在 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 的开头,这两个文件按圆圈相互包含。所以编译器不知道怎么编译。但是把那行放在最后会解决这个问题吗?为什么?先感谢您。

4

2 回答 2

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 已经部分涵盖了该部分):

#if !defined( MY_HEADER_INCLUDED_)
# define MY_HEADER_INCLUDED_
// Complete content goes here
#endif /* !defined( MY_HEADER_INCLUDED_) */

这样,当您第一次包含文件时,MY_HEADER_INCLUDED_将不会被定义(内容将被“放置”在代码中)。第二次(您将把它包括在圆圈中)MY_HEADER_INCLUDED_将被定义,因此将跳过完整的正文。

于 2012-11-14T09:56:13.843 回答
1

你是对的,这就是问题所在。你错了,编译器不知道如何编译——它知道,你只是用错了:)。

开头的包含防护AuthorizedObject.hpp(我假设它具有包含防护或#pragma once指令)将定义AUTHORIZED_OBJECT_H(或类似的)。之后,您包含List.h,而后者又包含 header AuthorizedObject.hpp。因为已经定义了包含保护宏AuthorizedObject,所以跳过了的定义,所以List不知道类型,但是使用它,所以你得到错误。

如果你把 include 放在最后,说明 的定义AuthorizedObject已经被编译器处理过了,所以在里面使用它List.h是有效的。

于 2012-11-14T09:56:37.783 回答