1. ホーム
  2. c++

[解決済み] フォワード宣言はどのような場合に使用できますか?

2022-03-15 17:01:17

質問

他のクラスのヘッダーファイルでクラスの前方宣言を行うことが許可される場合の定義を探しています。

ベースクラス、メンバとして保持されているクラス、メンバ関数に参照渡しされているクラスなど、どのようなクラスでもよいのでしょうか??

どのように解決するのですか?

コンパイラの立場になって考えてみてください。型をフォワード宣言したとき、コンパイラが知っているのはこの型が存在するということだけで、そのサイズやメンバー、メソッドについては何も知らないのです。そのため、この型は 不完全な型 . したがって、コンパイラは型のレイアウトを知る必要があるため、この型を使ってメンバーやベースクラスを宣言することはできません。

次のような前方宣言を想定しています。

class X;

できること、できないことを紹介します。

不完全な型にできること。

  • メンバーをポインタまたは不完全な型への参照とすることを宣言する。

    class Foo {
        X *p;
        X &r;
    };
    
    
  • 宣言する 不完全な型を受け付けたり返したりする関数やメソッド。

    void f1(X);
    X    f2();
    
    
  • 定義 不完全な型へのポインタや参照を受け付けたり返したりする(ただし、その型のメンバを使用しない)関数やメソッドです。

    void f3(X*, X&) {}
    X&   f4()       {}
    X*   f5()       {}
    
    

不完全な型ではできないこと。

  • ベースクラスとして使用する

    class Foo : X {} // compiler error!
    
    
  • メンバーの宣言に使用します。

    class Foo {
        X m; // compiler error!
    };
    
    
  • 定義 この型を使用した関数やメソッド

    void f1(X x) {} // compiler error!
    X    f2()    {} // compiler error!
    
    
  • そのメソッドまたはフィールドを使用し、実際には不完全な型の変数をデリファレンスしようとします。

    class Foo {
        X *m;            
        void method()            
        {
            m->someMethod();      // compiler error!
            int i = m->someField; // compiler error!
        }
    };
    
    

テンプレートに関して言えば、絶対的なルールはありません。不完全な型をテンプレートのパラメーターとして使えるかどうかは、その型がテンプレート内でどのように使われるかによります。

例えば std::vector<T> はパラメータが完全な型であることを要求していますが boost::container::vector<T> はありません。時には、特定のメンバー関数を使用する場合にのみ、完全な型が必要とされることがあります。 の場合です。 std::unique_ptr<T> は、例えば

十分に文書化されたテンプレートは、完全な型である必要があるかどうかを含め、そのパラメータのすべての要件をその文書で示すべきです。