1

私が持っている場合は.hで:

#pragma once

#include <xxxx.h>
#include "yyyy.h"

class AAAAAA;
class BBBBBB;

class ZZZZZZ
{
     public:

     // etc
 };

クラス AAAAAA を使用します。クラスの権利を前方宣言していますか?

なぜこれを行うのでしょうか?

必要ですか?

利点は何ですか?欠点?

4

4 に答える 4

3

なぜこれを行うのでしょうか?

コンパイラは宣言された名前しか認識しないためです。したがって、クラスを使用する場合は、クラスを宣言する必要があります。しかし、その定義がそのユーザーに依存する場合、ユーザーがクラスの定義に依存せず、その宣言 (= 名前) だけに依存する場合は、前方宣言で十分です。

特に、ユーザーがポインターまたは参照のみを必要とする場合、それは定義に依存しません。しかし、リストされているケース (標準的な非規範的な抜粋であるため、排他的であるとは主張していません) では、ユーザーは次の場合にクラス T の定義に依存します。

  • タイプ T のオブジェクトが定義されている (3.1)、または
  • T が new-expression のオブジェクト型または配列要素型として使用されている (5.3.4)、または
  • 左辺値から右辺値への変換が、型 T (4.1) のオブジェクトを参照する左辺値に適用される、または
  • 式が (暗黙的または明示的に) T 型に変換される (条項 4、5.2.3、5.2.7、5.2.9、5.4)、または
  • null ポインター定数ではなく、void* 以外の型を持つ式は、T への型ポインターまたは T への参照に、暗黙的な変換 (第 4 節)、dynamic_cast (5.2.7) または static_cast ( 5.2.9)、または
  • クラス メンバ アクセス演算子が型 T (5.2.5) の式に適用される、または
  • typeid 演算子 (5.2.8) または sizeof 演算子 (5.3.3) が型 T のオペランドに適用される、または
  • 戻り値の型または引数の型が T 型の関数が定義されている (3.1) か、呼び出されている (5.2.2)。
  • タイプ T の基本クラスを持つクラスが定義されている (第 10 節)、または
  • 型 T の左辺値が (5.17) に代入される、または
  • 例外宣言には、型 T、T への参照、または T へのポインターがあります (15.3)。

このような場合、前方宣言では不十分であり、完全に定義する必要があります。

必要ですか?

はい、必要な場合は必要です。次の場合は、両方のクラスが相互に参照しているためです。

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 の定義も必要でした。

利点は何ですか?欠点?

利点は、プログラムがコンパイルされることです。欠点は、スコープを別の名前で汚染してしまったことです。しかし、それはそれの必要悪です。

于 2010-09-04T17:12:01.660 に答える
3

参照またはポインターによってクラスを参照する場合、コンパイラーはそれが存在することを知る必要がありますが、他には何もありません。したがって、あなたがする必要があるのは、それを前方宣言することだけです。

ファイルがクラスのメソッドを呼び出すか、オブジェクト インスタンス (参照やポインターではない) を参照する場合、その型の定義は #include を使用してプルする必要があります。

大規模なコードベースでは、#includes を最小化するとコンパイル時間が短縮されます。

前方宣言は、#include の循環問題を回避するのにも役立ちます。

于 2010-09-04T17:13:28.990 に答える
0

そのタイプのみを参照する場合は、それが定義されているヘッダー全体をプルする必要はありません。コンパイラーに「これが定義されている」ことを伝える前方宣言を使用するだけで、コンパイラーはそのファイルでの使用に沿ったときに、そしてシンボルを解決できず、あなたを驚かせません。これは、「自分が何をしているかを知っている」ことの 1 つです。

于 2010-09-04T17:12:06.433 に答える
0

クラスが相互に参照する場合、前方宣言は不可欠です。簡単なケースを次に示します。

class A;

class B {
     void f(A&);
};

class A {
     void f(B&);
};

前方宣言なしではこれを行うことはできませんでした。2 つの相互再帰関数がある場合と同じで、そのうちの 1 つを前方宣言する必要があります。

于 2010-09-04T17:24:05.803 に答える