7

クラス A の内部でクラス B を宣言して使用し、A の外部で B を定義しようとしています。Bjarne Stroustrup が彼の著書「C++ プログラミング言語」でこれを使用している
ため、これが可能であることを知ってい ます (たとえば、293 ページ)。 String および Srep クラス)。

したがって、これは問題を引き起こす私の最小限のコードです

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 を見ようとしましたが、私が得たクローゼットはここここにありましたが、
それらは私の状況には当てはまりません。
ここからこれも読みましたが、問題は解決していません。

gcc と MSVC 2005 の両方で、これに関するコンパイラ エラーが発生します。

4

4 に答える 4

15

c->iはポインターを逆参照するstruct A::Bため、プログラムのこの時点で完全な定義が表示されている必要があります。

最も簡単な修正は、A非インラインのコンストラクターを作成し、 の定義後に本体を提供することですstruct A::B

于 2008-11-21T23:42:37.937 に答える
11

構造体 B の定義後に A のコンストラクターを定義します。

于 2008-11-21T23:44:23.970 に答える
7

これは、定義を宣言から分離しておく必要がある理由の良い例です。A::A()の定義の後にコンストラクターが定義されるように、物事の順序を変更する必要がありstruct A::Bます。

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

struct A::B
{
    int i;
};

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

int main()
{
    return 0;
}
于 2008-11-21T23:52:59.303 に答える
1

興味深いことに、Stroustrup の本の 293 ページ (「11.12 A String Class」) で同じ問題に遭遇しました。

印刷された本で提供されている例には問題があるようで、次のメソッドを struct 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...

私は少しグーグルで検索し、この文字列クラスの作成者による最新の実装を見つけました

このスレッドで言及されている問題を回避するために、これらのメソッドがインライン化されないように修正したようです。

于 2010-10-19T03:08:22.193 に答える