[英]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.