2010-04-08 201 views
32

是否有可能前向聲明一個嵌套類,然後用它作爲類型的混凝土(未指針/參考)外類的數據成員?C++嵌套類/向前聲明問題

I.E.

class Outer; 

class Outer::MaybeThisWay // Error: Outer is undefined 
{ 
}; 

class Outer 
{ 
MaybeThisWay x; 

class MaybeThatOtherWay; 

MaybeThatOtherWay y; // Error: MaybeThatOtherWay is undefined 
}; 
+0

代碼如下的循環鏈「外包含外包含外包含外......」 – Muxecoid 2010-04-08 13:56:15

+0

可能的重複[如何轉發聲明一個內部類?](http://stackoverflow.com/questions/1021793/how-do-i-forward-declare-an-inner-class) – 2015-07-15 09:34:07

回答

37

不能向前聲明一樣,嵌套類。

取決於你想要做什麼,也許你可以使用一個命名空間,而不是在外層上的類。您可以轉發,聲明這樣一類沒有問題:

namespace Outer { 
    struct Inner; 
}; 

Outer::Inner* sweets; // Outer::Inner is incomplete so 
         // I can only make a pointer to it 

如果你的外在絕對必須是一個類,你不能鞋拔到一個命名空間,那麼你所需要的外部是一個在您轉發聲明Inner的上下文中的完整類型。

class Outer 
{ 
    class Inner; // Inner forward-declared 
}; // Outer is fully-defined now 

Outer yes; // Outer is complete, you can make instances of it 
Outer::Inner* fun; // Inner is incomplete, you can only make 
        // pointers/references to it 

class Outer::Inner 
{ 
}; // now Inner is fully-defined too 

Outer::Inner win; // Now I can make instances of Inner too 
1

沒有,但是這有什麼錯

class Outer { 
public: //or protected or private 
    class Inner { 
    }; 

private: 
    Inner foo; 
}; 

正向聲明沒有意義在這裏,除非我失去了一些東西(這是有可能看到你的問題是缺乏很多細節)

請記住,如果一個類被聲明前,那麼你只能申報前申報類型的對象或引用指針。你不能做任何事情,包括訪問它的成員或功能。

+1

因爲內在不是前向宣佈它在那裏完全定義。 – CashCow 2016-05-13 13:18:10

+0

如果您要在這裏修改這些部分,該怎麼辦?也許公共部分中的某些函數使用私有變量,因此需要聲明它們,但Inner也需要私有變量。我們如何讓Inner在私人欄目中可見? – Sohaib 2017-05-29 12:23:43

1

如果一個類已經被前置聲明(但你沒有完整的定義還沒有),那麼你只能申報一個指向它,因爲編譯器還不知道班級的大小(也沒有其領域或方法的名稱)。

0

如果聲明MaybeThatOtherWay類型的屬性,而不是引用或指針,則編譯器必須知道該類的完整定義才能確定外部類的大小。因此,不能使用前向聲明和那種字段聲明,無論它是否是嵌套類。

15

沒有完全指定包含的類沒有辦法轉發聲明嵌套類。這個小動作還挺解決了這個問題,雖然

class Outer_Inner 
{ 
}; 

class Outer 
{ 
public: 
    typedef Outer_Inner Inner; 
}; 

這對我的作品在我的命名約定Outer_Inner是不是一個有效的類名,所以很明顯,它指的是嵌套類。

您仍然無法向前聲明嵌套類是這樣的:

class Outer::Inner; 

但至少它可以向前聲明:

class Outer_Inner; 

如果你不喜歡的方式Outer_Inner看起來你可以採用一個更適合你的口味的嵌套類的命名約定。 Outer__Inner,Outer_nested_Inner

+3

不要使用雙下劃線 - 包含兩個下劃線的名稱將保留給實施用於任何用途。請參閱http://stackoverflow.com/questions/228783/what-are-the-rules-about-using-an-underscore-in-a-c-identifier/228797#228797 – villintehaspam 2011-10-13 09:11:10

+0

這是我在這裏面對的同樣的問題嗎? http://stackoverflow.com/questions/20214740/nested-class-as-a-template-parameter-of-parent-class-in-c – 2013-11-27 07:47:50

0

如果你只是需要一個類型作爲函數參數或靜態變量,它可以在客戶端完成。例如,從外部接收事件通知:

接口:

class Client { 
public: 
private: 
    static void gotIt(int event); 
    class Helper; 
}; 

實現:

#include <outer.hpp> 

class Client::Helper { 
public: 
    static void fromOuter(Outer::Inner const& inner) 
    { 
     gotIt(inner.event()); 
    } 
};