私が持っている場合は.hで:
#pragma once
#include <xxxx.h>
#include "yyyy.h"
class AAAAAA;
class BBBBBB;
class ZZZZZZ
{
public:
// etc
};
クラス AAAAAA を使用します。クラスの権利を前方宣言していますか?
なぜこれを行うのでしょうか?
必要ですか?
利点は何ですか?欠点?
私が持っている場合は.hで:
#pragma once
#include <xxxx.h>
#include "yyyy.h"
class AAAAAA;
class BBBBBB;
class ZZZZZZ
{
public:
// etc
};
クラス AAAAAA を使用します。クラスの権利を前方宣言していますか?
なぜこれを行うのでしょうか?
必要ですか?
利点は何ですか?欠点?
なぜこれを行うのでしょうか?
コンパイラは宣言された名前しか認識しないためです。したがって、クラスを使用する場合は、クラスを宣言する必要があります。しかし、その定義がそのユーザーに依存する場合、ユーザーがクラスの定義に依存せず、その宣言 (= 名前) だけに依存する場合は、前方宣言で十分です。
特に、ユーザーがポインターまたは参照のみを必要とする場合、それは定義に依存しません。しかし、リストされているケース (標準的な非規範的な抜粋であるため、排他的であるとは主張していません) では、ユーザーは次の場合にクラス T の定義に依存します。
このような場合、前方宣言では不十分であり、完全に定義する必要があります。
必要ですか?
はい、必要な場合は必要です。次の場合は、両方のクラスが相互に参照しているためです。
class A;
class B {
// forward declaration needed
void f(A);
};
class A {
void f(B);
};
// "- a function with a return type or argument type of type T is defined"
void B::f(A) {
}
メンバー関数の定義には、宣言だけでなく、クラス A の定義も必要でした。
利点は何ですか?欠点?
利点は、プログラムがコンパイルされることです。欠点は、スコープを別の名前で汚染してしまったことです。しかし、それはそれの必要悪です。
参照またはポインターによってクラスを参照する場合、コンパイラーはそれが存在することを知る必要がありますが、他には何もありません。したがって、あなたがする必要があるのは、それを前方宣言することだけです。
ファイルがクラスのメソッドを呼び出すか、オブジェクト インスタンス (参照やポインターではない) を参照する場合、その型の定義は #include を使用してプルする必要があります。
大規模なコードベースでは、#includes を最小化するとコンパイル時間が短縮されます。
前方宣言は、#include の循環問題を回避するのにも役立ちます。
そのタイプのみを参照する場合は、それが定義されているヘッダー全体をプルする必要はありません。コンパイラーに「これが定義されている」ことを伝える前方宣言を使用するだけで、コンパイラーはそのファイルでの使用に沿ったときに、そしてシンボルを解決できず、あなたを驚かせません。これは、「自分が何をしているかを知っている」ことの 1 つです。
クラスが相互に参照する場合、前方宣言は不可欠です。簡単なケースを次に示します。
class A;
class B {
void f(A&);
};
class A {
void f(B&);
};
前方宣言なしではこれを行うことはできませんでした。2 つの相互再帰関数がある場合と同じで、そのうちの 1 つを前方宣言する必要があります。