简体   繁体   English

将头文件(.h)放在另一个文件(.h 或 .cpp)的开头和结尾的区别

[英]difference between putting head file(.h) at the beginning and end of another file(.h or .cpp)

Recently , I was compiling libfacebookcpp on mac os.最近,我在 mac os 上编译 libfacebookcpp。 I found a strange usage which I can't understand.我发现了一个我无法理解的奇怪用法。 There are two files, AuthorizedObject.hpp and List.hpp.有两个文件,AuthorizedObject.hpp 和 List.hpp。 At the end of file AuthorizedObject.hpp,there is one line :#include "List.hpp".Now I compile successfully.在文件 AuthorizedObject.hpp 的末尾,有一行:#include "List.hpp"。现在我编译成功了。 But when I move that line to the beginning, error occurs.但是当我将该行移到开头时,就会发生错误。 The skeleton of the codes are:代码的骨架是:

//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
...
}

I guess if put that line(#include "List.h") at the beginning of AuthorizedObject.hpp, the two files include each other by circle.我想如果把那行(#include "List.h") 放在 AuthorizedObject.hpp 的开头,这两个文件会通过圆圈相互包含。 So the compiler don't know how to compile.But put that line at the end will solve this problem?所以编译器不知道如何编译。但是把那行放在最后会解决这个问题吗? Why?为什么? Thank you in advance.先感谢您。

The difference is in what order classes/functions/... are defined, for example:不同之处在于 classes/functions/... 的定义顺序,例如:

#include "one.h"
void foo(bar &);

// Will result into:
class bar {};
void foo(bar&);

Which is valid code.这是有效的代码。 On the other hand:另一方面:

void foo(bar &);
#include "one.h"

// Will result into statements in different order:
void foo(bar&);
class bar {};

Which means using class bar before it was declared, thus error.这意味着在声明之前使用class bar ,因此会出错。 You also may need to make sure that no declaration will be processed twice ( UmNyobe already covered that partially ):您可能还需要确保没有声明将被处理两次( UmNyobe 已经部分涵盖了这一点):

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

This way when you include file for the first time, MY_HEADER_INCLUDED_ won't be defined (contents will be "placed" inside the code).这样,当您第一次包含文件时,将不会定义MY_HEADER_INCLUDED_ (内容将被“放置”在代码中)。 The second time (you will include it in the circle) MY_HEADER_INCLUDED_ will be defined and therefore complete body will be skipped.第二次(您将其包含在圆圈中) MY_HEADER_INCLUDED_将被定义,因此将跳过完整的主体。

You're right, that's the problem.你是对的,这就是问题所在。 You're wrong that the compiler doesn't know how to compile - it does, you're just using it wrong :).你错了,编译器不知道如何编译——它知道,你只是用错了:)。

The include guards at the beginning of AuthorizedObject.hpp (I assume it has include guards or a #pragma once directive) will define AUTHORIZED_OBJECT_H (or similar). AuthorizedObject.hpp开头的包含守卫(我假设它有包含守卫或#pragma once指令)将定义AUTHORIZED_OBJECT_H (或类似的)。 After that, you include List.h , which in turn includes the header AuthorizedObject.hpp .之后,您包含List.h ,后者又包含标题AuthorizedObject.hpp Because the include guard macro was already defined, the definition of AuthorizedObject is skipped, so List doesn't know about the type, but is uses it, so you get the error.因为已经定义了包含保护宏,所以跳过了AuthorizedObject的定义,所以List不知道类型,而是使用它,所以你得到了错误。

If you move the include at the end, the definition of AuthorizedObject was already processed by the compiler, so using it inside List.h is valid.如果在最后移动包含,则AuthorizedObject的定义已经由编译器处理,因此在List.h使用它是有效的。

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

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