2008-11-21 148 views
7

我想聲明和使用B類A類 的內部和定義31b的外側A.
我知道一個事實,這是可能的,因爲Bjarne的Stroustrup的
使用這他的書「The C++ programming language」
(第293頁,例如String和Srep類)。C++嵌套類向前聲明錯誤

所以這是我最小的代碼引起的問題

class A{ 
struct B; // forward declaration 
B* c; 
A() { c->i; } 
}; 

struct A::B { 
/* 
* we define struct B like this becuase it 
* was first declared in the namespace A 
*/ 
int i; 
}; 

int main() { 
} 

這個代碼給出了G ++以下編譯錯誤:

tst.cpp: In constructor ‘A::A()’: 
tst.cpp:5: error: invalid use of undefined type ‘struct A::B’ 
tst.cpp:3: error: forward declaration of ‘struct A::B’ 

我想看看C++ FAQ和closeset我得到的是herehere,但
那些不適用於我的情況。
我也從這裏read this,但它不能解決我的問題。在這個

回答

11

定義用於構造結構B.

+0

是定義後`inline`關鍵字定義函數爲內聯,該工作 謝謝:) – xxxxxxx 2008-11-21 23:52:04

15

表達c->i

GCC和MSVC 2005年給予編譯器錯誤解引用指針struct A::B這樣一個完整的定義必須在程序中的這一點上是可見的。

最簡單的解決方法是使A的構造函數非內聯,並在struct A::B的定義後爲其提供一個正文。

+0

或者,使用結構B的 – Phlucious 2013-02-07 19:11:58

7

這就是爲什麼你想保留的定義從聲明分開一個很好的例子後定義。您需要更改事物的順序,以便在定義struct A::B後定義構造函數A::A()

class A 
{ 
    struct B; 
    B* c; 
    A(); 
}; 

struct A::B 
{ 
    int i; 
}; 

A::A() { c->i; } 

int main() 
{ 
    return 0; 
}
1

有趣的是,我碰到了Stroustrup書中提到的第293頁('11 .12 A String Class')的問題。

在印刷書提供的例子似乎有過錯,並提供以下方法爲內聯,而不是的結構SREP

class String { 
    // ... 
    void check(int i) const { if (i<0 || rep->sz <=i) throw Range(); } 
    char read(int i) const { return rep->s[i]; } 
    void write(int i, char c) { rep=rep->get_own_copy(); rep->s[i]=c; } 
    ...etc... 

我GOOGLE了一下定義後定義它們,發現作者的這個字符串類的最新實現,可在這裏: http://www2.research.att.com/~bs/string_example.c

他似乎已經修改它,以便這些方法不再內聯,以避免在此線程中提到的問題。