簡體   English   中英

轉發在標頭中聲明std :: size_t

[英]Forward declare std::size_t in a header

經過一些研究后,我發現如果前向聲明可以,我應該盡量避免在我的頭文件中包含#include 我怎樣才能轉發聲明std::size_t 或者我必須在頭文件中#include <cstddef>嗎?

文件my_string.h

#ifndef MY_STRING_H_
#define MY_STRING_H_

extern std::size_t;

namespace my
{
        class string
        {
        public:
                std::size_t length() const { return len; }
                const char *c_str() const;
        private:
                std::size_t len;
        }
}

#endif

文件my_string.cpp

#include "my_string.h"

#include <cstddef>

const char *my::string::c_str() const
{
        for (std::size_t i = 0; i < len; ++i)
                ;       // do stuff ...

        return something;
}

顯然這些例子並不完整......

我收到錯誤: error: 'size_t' in namespace 'std' does not name a type (來自my_string.h )。

編輯:謝謝你的答案。 我想我浪費時間試圖強制不包括這個標題,但我只是想確定我沒有錯過一些簡單的東西。

extern用於函數和變量,不用於類型別名。 類型別名是使用typedef定義的。

如果你想為你自己的一個類型做這個,你可以從標題中復制它的typedef,並避免包含頭,但即使這樣你也會得到重復的代碼,這是一個維護責任。

size_t問題更嚴重:因為它背后的內置類型與系統有關,你必須重現相同的邏輯或風險不兼容。 與僅包含標題相比,這兩個選項都相當糟糕。

如果要開發庫,則應避免在頭文件中包含頭文件,但始終需要在cpp文件中包含必需的頭。 因此,最好只在cpp文件中包含特定的頭文件,並在頭文件中使用前向聲明。 但是如果您在系統標頭中具有依賴性,那么您應該在頭文件中包含該系統標頭。

提示是通過在源文件(* .cpp,* .c)中包含頭文件,我們阻止最終用戶解析我們開發的庫的鏈接器依賴性。

size_t是一個typedef,你不能用它與extern - extern用於變量或函數。

如果你確保在每一個之前就足夠了:

#include "my_string.h"

#include <cstddef>

它的好習慣是始終包含第一個編譯器頭文件(帶有<>的onces),然后是本地頭文件(帶有“”的包含)。

如果你需要一個類型定義為std :: size_t,那么即使在頭文件中也要包含它。 所有標題都應該有適當的包含防范以防止多個定義。 保持只在.cpp文件中包含標題的習慣真的很難。 編譯器擅長優化多個頭包括,Visual Studio提供預編譯頭,也是#pragma once

不要求標題包含在特定順序中。 這是一個完整的發展噩夢,可能需要很長時間才能讓人們深入了解代碼。 確保標題在聲明方面是“自包含”的要好得多。

這要求標題中的任何依賴項要么包含在內,要么更好:前向聲明,這樣所有聲明都可以在沒有任何遺漏的情況下完成。

如果使用前向聲明,CPP文件仍需要包含額外的標頭以完全定義所使用的數據類型,但不應使順序變得重要。

在最初的問題中,my_string.h使用size_t作為成員變量,因此必須對其進行定義,而我更傾向於包含所需的cstddef或stddef.h,而不是期望my_string.h的用戶首先包含它。 在my_string.h的任何包含之前要求包含其中一個標題沒有額外的好處,因為將完成相同數量的包含。

最后,由於size_t是一個typedef,因此技術上可以在my_string.h頭中自己鍵入def,因為在C ++中可以使用多個相同的typedef。 但是,我建議不要這樣做,因為size_t的大小取決於平台。

暫無
暫無

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

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