簡體   English   中英

C ++循環依賴 - 命名空間與結構

[英]C++ circular dependency - namespace vs struct

請教育我。 為什么編譯:

struct compiles
{
    struct A;
    struct B
    {
        B(const A &a) : member(a.member) { }
        int member;
    };
    struct A
    {
        A(const B &b) : member(b.member) { }
        int member;
    };
};

雖然這不是:

namespace doesnt
{
    struct A;
    struct B
    {
        B(const A &a) : member(a.member) { }
        int member;
    };
    struct A
    {
        A(const B &b) : member(b.member) { }
        int member;
    };
}

(在MSVC 9.0中)

一次處理class / struct / union定義的主體,允許引用稍后定義的類的成員。 namespace從上到下進行處理, struct A的前向聲明不允許您在沒有定義的情況下使用其成員。 嘗試將B的構造函數的定義移到類外,這樣就可以將它放在A的定義之后。

在C ++中,類范圍很特殊。 任何延伸到或超過類定義的聲明都會自動擴展到由其成員定義(3.3.6 [basic.scope.class])定義的區域。

這意味着,在第一種情況下兩者的第一個聲明struct A和的完整定義struct A是在體內可見B和它的構造。

這不適用於命名空間范圍,因此在第二種情況下, B的構造函數中的a.member是一個錯誤,因為struct A的定義尚不可見。

[也使用g ++ 4.2進行測試]第一個編譯是因為編譯器在實際編譯嵌套結構之前完全獲取結構中定義的所有類型(考慮使用稍后出現在類中的私有屬性的公共內聯方法)。 在命名空間內,編譯器只是從上到下工作,沒有特殊規則。

如果你將構造函數的實現移動到.cpp文件,它們都應該編譯。

暫無
暫無

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

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