struct X;
struct Y {
void f(X*);
};
struct X { //definition
private:
int i;
public:
friend void Y::f(X*);
<SNIP'd>
};
「構造体には、型のオブジェクトを変更する
Yメンバー関数があります。C++コンパイラでは、参照する前にすべてを宣言する必要があるため、これは少し難問です。したがって、構造体は、そのメンバーをとして宣言する前に宣言する必要があります。構造体の友人。しかし、宣言されるためには、構造体が最初に宣言されなければなりません!f()XYY::f(X*)XY::f(X*)Xこれが解決策です。オブジェクト
Y::f(X*)のアドレスを取ることに注意してください。コンパイラは、型のサイズに関する完全な情報がなくても、渡されるオブジェクトに関係なく、固定サイズのアドレスを渡す方法を常に知っているXため、これは重要です。」
だからここにあります:
struct X; struct Y { ... }; struct X { ... };
私の質問はこれです:
Xコンパイラが、不完全に宣言されていると主張するのはなぜstruct X;ですか?結局のところ、作者が指摘しているように、「コンパイラは、固定サイズのアドレスを渡す方法を常に知っています」。これは、コンパイラーに
X構造体であり、すぐに続くことを通知する宣言にすぎません。そのため、コンパイラーが次の文字を入力するように強く主張しているのはなぜですかX。結局、私はXそれ自体を使用していませんか?その時点で生成されているアセンブリ言語コードはありません。X*そしてそれが確かに読むとき、それはそれがアドレス(ポインタ)であると言うことができます。なぜ:struct X;必要ですか?関数を宣言することの全体的なポイントは、実際に使用する前に型をチェックすることです。だから私がそうするなら:
int foo(void); foo(30);コンパイラは遠吠えします。しかし、上記で、私が言わなければ、それは
struct X;どのような違いを生むのでしょうか?X彼は私の(関数名)のスペルをチェックしているだけですか?構造体YとXの配置を逆にしないのはなぜですか?そのように:
struct Y; struct X { ... }; struct Y { ... };
私は得る:エラー:不完全なタイプの無効な使用
'struct main()::Y'Y明らかに、コンパイラは( )の不完全な型指定に満足していませんstruct Y;。しかし、どのような貴重な情報が欠けていますか?結局のところstructY; すぐに続くコンパイラーに通知する必要がありYます(Q1で行っていたのと同じですstruct X; struct Y {}; struct X{};) 。なぜ作者は構造体
Xを定義として参照するのですか?私がそうする場合:struct X { ... };これは確かに宣言ですか?そして、私がそのように構造をインスタンス化するとき:Xfoo; それならそれは定義ですか?正しい?これを行うにはどうすればよいですか:
struct X { friend void Y::f(X*); void f(Y*); }; struct Y { friend void X::f(Y*); void f(X*); };