[解決済み] フォワード宣言はどのような場合に使用できますか?
質問
他のクラスのヘッダーファイルでクラスの前方宣言を行うことが許可される場合の定義を探しています。
ベースクラス、メンバとして保持されているクラス、メンバ関数に参照渡しされているクラスなど、どのようなクラスでもよいのでしょうか??
どのように解決するのですか?
コンパイラの立場になって考えてみてください。型をフォワード宣言したとき、コンパイラが知っているのはこの型が存在するということだけで、そのサイズやメンバー、メソッドについては何も知らないのです。そのため、この型は 不完全な型 . したがって、コンパイラは型のレイアウトを知る必要があるため、この型を使ってメンバーやベースクラスを宣言することはできません。
次のような前方宣言を想定しています。
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>
は、例えば
十分に文書化されたテンプレートは、完全な型である必要があるかどうかを含め、そのパラメータのすべての要件をその文書で示すべきです。
関連
-
[解決済み】C++の余分な資格エラー
-
[解決済み】C++ - ステートメントがオーバーロードされた関数のアドレスを解決できない。
-
[解決済み] static_cast, dynamic_cast, const_cast, reinterpret_cast はいつ使うべきですか?
-
[解決済み] なぜテンプレートはヘッダーファイルでしか実装できないのですか?
-
[解決済み] スマートポインターとは何ですか?
-
[解決済み] なぜ、オブジェクトそのものではなく、ポインタを使用しなければならないのですか?
-
[解決済み] 仮想デストラクタはいつ使うのか?
-
[解決済み] 関数のパラメータに 'const' を使用する
-
[解決済み】定義と宣言の違いは何ですか?
-
[解決済み】C++のforward宣言とは何ですか?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み】C++ クラスヘッダが含まれているときに「不明な型」があるのはなぜですか?重複
-
[解決済み】致命的なエラー LNK1169: ゲームプログラミングで1つ以上の多重定義されたシンボルが発見された
-
[解決済み】C++ 式はポインタからオブジェクトへの型を持っている必要があります。
-
[解決済み】デバッグアサーションに失敗しました。C++のベクトル添え字が範囲外
-
[解決済み】エラー。switchステートメントでcaseラベルにジャンプする
-
[解決済み】Visual Studio 2013および2015でC++コンパイラーエラーC2280「削除された関数を参照しようとした」が発生する
-
[解決済み】CMakeエラー at CMakeLists.txt:30 (project)。CMAKE_C_COMPILER が見つかりませんでした。
-
[解決済み] gdbを使用してもデバッグシンボルが見つからない
-
[解決済み】'std::cout'への未定義の参照
-
[解決済み】未定義の型を使用する【重複あり