簡體   English   中英

將頭文件(.h)放在另一個文件(.h 或 .cpp)的開頭和結尾的區別

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

最近,我在 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 的開頭,這兩個文件會通過圓圈相互包含。 所以編譯器不知道如何編譯。但是把那行放在最后會解決這個問題嗎? 為什么? 先感謝您。

不同之處在於 classes/functions/... 的定義順序,例如:

#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_將被定義,因此將跳過完整的主體。

你是對的,這就是問題所在。 你錯了,編譯器不知道如何編譯——它知道,你只是用錯了:)。

AuthorizedObject.hpp開頭的包含守衛(我假設它有包含守衛或#pragma once指令)將定義AUTHORIZED_OBJECT_H (或類似的)。 之后,您包含List.h ,后者又包含標題AuthorizedObject.hpp 因為已經定義了包含保護宏,所以跳過了AuthorizedObject的定義,所以List不知道類型,而是使用它,所以你得到了錯誤。

如果在最后移動包含,則AuthorizedObject的定義已經由編譯器處理,因此在List.h使用它是有效的。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM